害 我好菜啊,太久没打了,只会俩,有一个还是赛后过的,我的分啊。。
A.
这是我想了半个小时的水题,直接判断两倍就完了。。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll maxn=1e5+1000;
const ll inf=0x3f3f3f3f;
ll t,n,l,r;
ll gcd(ll a,ll b){
if(b==0){
return a;
}else return gcd(b,a%b);
}
int main(){
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
cin>>l>>r;ll check=0;
ll tem=r/l;
if(tem==1){
cout<<-1<<' '<<-1<<endl;
}else cout<<l<<' '<<tem*l<<endl;
}
return 0;
}
B.
给出一个数列,一开始在1处,并有1块钱,现在要走k步,最多往左走z步,且每次往左走之前要往右走。
记录一开始直接走到k+1格的总价值,循环找到两步之和最大的地方,然后每次减2步再加上最大和,并记录过程中的最大这就可以了。害,原来在往回走的时候要取中间的最大值,我直接记录了最终值。。惨。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll maxn=2e5+1000;
const ll inf=0x3f3f3f3f;
ll t,n,k,z;
ll a[maxn],sum[maxn],maxi,maxs,sum2[maxn],s2[maxn];
int main(){
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
cin>>n>>k>>z;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
for(int i=2;i<=n;i++) sum2[i]=a[i]+a[i-1];
ll res=sum[k+1],end=k+1;
maxi=-1;
for(int p=1;p<=z;p++){
end=k+1-p*2;
maxi=-1;
if(end<1)break;
for(int i=2;i<=end+1;i++) maxi=max(maxi,sum2[i]);
res=max(res,sum[end]+maxi*p);
}cout<<res<<endl;
}
return 0;
}
C.
结果肯定是要为2为周期,且要首尾不一样.注意到元素都是0-9,可以套两层循环来判断循环的元素。
最后返回结果的时候我掉坑了,如果总有效个数(就是剩下的那些里面的)为奇数时,要判断是不是只有一个元素,如果只有一个就是直接剪掉有效个数,否则有效个数会少一个(因为要在首或尾里面再删一个)。
T_T 掉了一百来分,心疼。。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll maxn=2e5+1000;
const ll inf=0x3f3f3f3f;
ll t,n,k,z;
string a;
set<char> ch;
ll num(char x,char y){
ll con=0,end;
char start;
for(int i=0;i<a.size();i++){
if(con%2==0){
if(a[i]==x)con++;
}else{
if(a[i]==y)con++;
}
}if(con%2==1){
if(con==1) return a.size()-1;
else{
if(x==y) return a.size()-con;
else return a.size()-(con-1);
}
}else{
return a.size()-con;
}
}
int main(){
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
cin>>a;
for(int i=0;i<a.size();i++){
ch.insert(a[i]);
}
if(ch.size()==1){
cout<<0<<endl;
continue;
}else{
ll res=inf;
for(char i='0';i<='9';i++){
for(int j='0';j<='9';j++){
res=min(res,num(i,j));
}
}cout<<res<<endl;
}
ch.clear();
}
return 0;
}
E.
假设每年有\(m\)个月,每个月有\(d\)天,每个星期有\(w\)天,每次询问有序数对\((x,y)\)使得在第\(x\)月的第\(y\)天和第\(y\)月的第\(x\)天对应的星期相同。
依据题意有:
\(\left[ \left( x-1 \right) d+y \right] \%w=\left[ \left( y-1 \right) d+x \right] \%w\)
\(\left( d-1 \right) \left( x-y \right) \%w=0\),设$g=gcd\left( d,w \right) $,那么: \(\cfrac{\left( d-1 \right)}{g}\left( x-y \right) =k\cfrac{w}{g}\)
所以当\(d\ne1\)时,\(x-y\)必为\(\cfrac{w}{g}\)的倍数;当\(d=1\)时无解,或者所有的\((x,y)\)都不满足\(x<y\),然后就是算的时候找一下规律。也没那么难,就是昨天的\(A\)太\(tm\)搞心态了。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
int t; cin >> t;
while (t--) {
ll m, d, w;
cin >> m >> d >> w;
if (d == 1) {
cout << "0\n";
continue;
}
ll g = __gcd(w, d - 1);
ll ww = w / g;
ll top = min(d, m);
ll num = (ll)floor(1.0 * top / ww);
ll ans = top * num - num * (num + 1ll) / 2ll * ww;
cout << ans << '\n';
}
return 0;
}