目录
A. Plus or Minus
思路:按题目要求输出即可。
void solve() {
int a,b,c;
cin>>a>>b>>c;
if(a-b==c)cout<<"-"<<endl;
else cout<<"+"<<endl;
}
B. Grab the Candies
思路:把偶数全放前面,把奇数全放后面,这样只用看偶数之和是否严格大于奇数之和。
void solve() {
int n;
cin>>n;
int sum1=0,sum2=0;
FOR(1,n) {
int x;
cin>>x;
if(x&1)sum1+=x;
else sum2+=x;
}
if(sum2>sum1)yes;
else no;
}
C. Find and Replace
思路:先模拟赋值,最后看字符串是否01相间
void solve() {
map<char,int>mp;
int n;
cin>>n;
string s;
cin>>s;
FOR(0,n-1) {
if(mp[s[i]]) {
if(mp[s[i]]==-1)s[i]='0';
else s[i]='1';
continue;
}
if(i&1)mp[s[i]]=1,s[i]='1';
else mp[s[i]]=-1,s[i]='0';
}
FOR(0,n-2) {
if(s[i]==s[i+1]) {
no;
return;
}
}
yes;
}
D. Odd Queries
思路:若要数组总和为奇数,则数组内有奇数个奇数。利用前缀和快速判断改变完之后数组内奇数的个数即可。
void solve() {
int n,q;
cin>>n>>q;
FOR(1,n)cin>>a[i],sum[i]=sum[i-1]+a[i]%2;
while(q--) {
int l,r,k;
int s=0;
cin>>l>>r>>k;
s+=sum[l-1]+sum[n]-sum[r];
s+=(k%2)*(r-l+1);
if(s%2)yes;
else no;
}
}
E. Interview
思路:利用前缀和二分判断区间内的总和是否合法,若左区间合法则r=mid,反之l=mid+1,直至l=r。
void solve() {
int n,x;
cin>>n;
FOR(1,n) {
cin>>x;
sum[i]=sum[i-1]+x;
}
int l=1,r=n;
while(l!=r) {
int mid=(l+r)/2;
cout<<"? "<<mid-l+1<<" ";
FOR(l,mid)cout<<i<<" ";
cout<<endl;
cin>>x;
if(sum[mid]-sum[l-1]!=x)r=mid;
else l=mid+1;
}
cout<<"! "<<l<<endl;
}
F. Bouncy Ball
思路:按照题意模拟即可,主要就是判断有没有重复一开始的两步行为,若有则输出-1。
void solve() {
map<string,PII>mp;
mp["DL"]= {1,-1},mp["DR"]= {1,1},mp["UR"]= {-1,1},mp["UL"]= {-1,-1};
int n,m,x1,y1,x2,y2,st=0,st2=0;
string s;
cin>>n>>m>>x1>>y1>>x2>>y2>>s;
int xp=x1,yp=y1,xp2,yp2;//xp,yp记录第一步动作
auto now=mp[s];
if(x1+now.first<1||x1+now.first>n)xp2=x1-now.first;//xp2,yp2记录第二步动作
else xp2=x1+now.first;
if(y1+now.second<1||y1+now.second>m)yp2=y1-now.second;
else yp2=y1+now.second;
while(1) {
if(x1==x2&&y1==y2) {
cout<<st<<endl;
return;
}
int x=x1+now.first,y=y1+now.second;
int f=0;
if(x<1||x>n)now.first=-now.first,st++,f=1;
if(y<1||y>m)now.second=-now.second,st++,st-=f;//减去f是为了特判撞到墙角的情况,若不判会使st+2
x1=x1+now.first,y1=y1+now.second;
if(x1==xp&&y1==yp) { //若第一步重合了则进一步判断下一步是否重合
int kx,ky;
if(x1+now.first<1||x1+now.first>n)kx=x1-now.first;
else kx=x1+now.first;
if(y1+now.second<1||y1+now.second>m)ky=y1-now.second;
else ky=y1+now.second;
if(kx==xp2&&ky==yp2) {
cout<<-1<<endl;
return;
}
}
}
}
G. Subsequence Addition
思路:我们考虑最“坏”的情况,数组为1,1,2,4,8,16......,可以发现它们都是2的幂次,通过二进制的思想可以发现他组成数的范围为1~sum,所以1~sum都能利用前面的数组成,利用前缀和判断下一个数是否大于sum即可。
void solve() {
int n;
cin>>n;
FOR(1,n)cin>>a[i];
sort(a+1,a+n+1);
FOR(1,n) sum[i]=sum[i-1]+a[i];
if(a[1]!=1) {
no;
return;
}
FOR(2,n) {
if(a[i]>sum[i-1]) {
no;
return;
}
}
yes;
}