Codeforces Round 960 (Div. 2)-补题
A. Submission Bait
当某个数字出现次数为奇数时,Alice就可通过选取该数取得胜利
void solve(){cin>>n;map<int,int> mp;for(int i=0;i<n;i++) cin>>a[i],mp[a[i]]++;for(int i=0;i<n;i++){if(mp[a[i]]%2){cout<<"YES"<<endl;return;}}cout<<"NO"<<endl;
}
B. Array Craft
构造题,前缀和最大即在x位置后不能出现连续的一段1,且x+1位置必须为-1,后缀和最大即y位置前不能出现连续的一段1,且y-1位置为-1,x+1位置后和y-1位置前交替1和-1,绝对值和均为0或1,x和y间均为1,这样构造就可在x处取最大前缀和,而且索引是最小的,y处取最大后缀和,而且索引是最大的
void solve(){cin>>n>>x>>y;for(int i=1;i<y;i++){if((y-1)%2){if(i%2) cout<<-1<<" ";else cout<<1<<" "; }else{if(i%2) cout<<1<<" ";else cout<<-1<<" ";}}for(int i=y;i<=x;i++) cout<<1<<" ";for(int i=x+1;i<=n;i++){if((x+1)%2){if(i%2) cout<<-1<<" ";else cout<<1<<" ";}else{if(i%2) cout<<1<<" ";else cout<<-1<<" ";}}cout<<endl;
}
C. Mad MAD Sum
看了大佬发现的性质,第一轮整理后,数列会变成单调不减的数列,第二轮整理后,除了最大数可能为1,数列中剩下的元素的数量必然大于2,从第三轮开始,就是每次数列右移一位,所以就可以根据 ai*(n-i) 来算对答案的贡献了,
void solve(){cin>>n;ll sum=0,maxs=0;map<int,int> mp; for(int i=0;i<n;i++) cin>>a[i],sum+=a[i];for(int i=0;i<n;i++){mp[a[i]]++;if(mp[a[i]]>=2&&maxs<a[i]) maxs=a[i];a[i]=maxs;sum+=a[i];}mp.clear();maxs=0;//for(int i=0;i<n;i++) cout<<a[i]<<" ";cout<<endl;for(int i=0;i<n;i++){mp[a[i]]++;if(mp[a[i]]>=2&&maxs<a[i]) maxs=a[i];a[i]=maxs;}mp.clear();//for(int i=0;i<n;i++) cout<<a[i]<<" ";cout<<endl;for(int i=0;i<n;i++){sum+=a[i]*(n-i);//cout<<i<<" "<<a[i]<<" "<<sum<<endl;}cout<<sum<<endl;
}
D. Grid Puzzle
又是看大佬的,用tag1数组表示第一二个块,tag2数组表示第三四块,小于等于2的行均用操作一,这样是最优的,因为可以涉及到下一行的两个,小于等于4的行,如果有块被上一行的操作消除,就考虑消剩下的块,如果大于4的行,直接用操作二
void solve(){int ans=0;cin>>n;for(int i=1;i<=n;i++) cin>>a[i],tag1[i]=tag2[i]=0;for(int i=1;i<=n;i++){if(!a[i]) continue;if(tag1[i]&&a[i]<=2) continue;if(tag1[i]&&tag2[i]&&a[i]<=4) continue;if(a[i]<=2) tag1[i]=tag1[i+1]=1;else if(a[i]<=4){if(tag1[i]) tag2[i]=tag2[i+1]=1;else if(tag2[i]) tag1[i]=tag1[i+1]=1;} ans++;}cout<<ans<<endl;
}