Codeforces Round #829 (Div. 2)(补题中)
战绩:
A. Technical Support
出现问题就要有答案,直接模拟。
int main() { read(T); while(T--) { cin>>n; cin>>s; q=0; for(int i=0;i<n;i++) { if(s[i]=='Q') q++; if(s[i]=='A'&&q>0) q--; } if(q) cout<<"No"<<endl; else cout<<"Yes"<<endl; } return 0; }
B. Kevin and Permutation
这题有些细节可以好好说到说到
令X=n/2(向下取整),那么我们每次应该是让1和x+1、2和x+2、3和x+3为一组一组。
那么就有两个的考量,组和组之间的排布和组间两个数字的排布。
那么如果组内递增排布而组和组之间也递增排列,例如(1 4 2 5 3 6)这样排列的话,那么组和组之间的差值会变小,而如果组内和组与组之间反向排布(4 1 5 2 6 3)这样输出就不会出问题。
int main() { read(T); while(T--) { cin>>n; int x=n/2; for(int i=1;i<=n/2;i++) cout<<x+i<<" "<<i<<" "; if(n%2) cout<<n<<" "; cout<<endl; } return 0; }
C1/2. Make Nonzero Sum
这题有个很有趣的事情。
C1我很早就完成,但是C2却卡在最后才完成。
然而C2的代码是我C1基本没变动交上去的。
C1的思路和C2的是一样的,但是考虑问题的视点不一样了,结果我导致我一直以为C2需要很大的变动,然而实际上并没有影响。
思路:
首先我们可以把每个数字一个个框柱,那么最后就会有一个总体贡献,我们要让这个贡献为0。对于每一个数字1或-1,实际上将这个数字变号,都会造成正负2点的贡献,因此如果整体贡献为奇数,实际上是没有办法的。
如果为偶数,那么我们只需要将要变化的数字和它前一个数字合并成一组,答案每次就会+-2,我们就可以像这样将总体贡献拉为0.
int main() { read(T); while(T--) { cin>>n; tot1=0;tot2=0; for(int i=1;i<=n;i++) { cin>>a[i]; if(a[i]==1) tot1++; else if(a[i]==-1)tot2++; } a[n+1]=-3; ll lim=abs(tot1-tot2); v1.clear();v2.clear(); if(lim&1) {cout<<-1<<endl;continue;} else { if(tot1>tot2) { for(int i=1;i<=n;i++) { if(lim&&(a[i+1]==1)) { lim-=2; v1.push_back(i); v2.push_back(i+1); i++; } else { v1.push_back(i); v2.push_back(i); } } } else { for(int i=1;i<=n;i++) { if(lim&&(a[i+1]==-1)) { lim-=2; v1.push_back(i); v2.push_back(i+1); i++; } else { v1.push_back(i); v2.push_back(i); } } } } cout<<v1.size()<<endl; for(int i=0;i<v1.size();i++)cout<<v1[i]<<" "<<v2[i]<<endl; } return 0; }
D.Factorial Divisibility
我没证明,靠感觉做的。
设n!=a1!+a2!+a3!+...+an!
我们有(n+1)!=(n+1)*n!也就是说n+1个n的阶乘能变成n+1的阶乘。
那我们把所有的阶乘按这个公式一个个往上累积,如果能累积成n+1阶乘的倍数个,就输出yes。
证明也简单:你可以把数组直接先拆开来,全变成1!=1,然后再全部累积起来,道理是一样的。
int main() { //read(T); T=1; while(T--) { cin>>n>>x; for(int i=1;i<=n;i++) { cin>>a[i]; buc[a[i]]++; } bool flag=0; for(int i=1;i<x;i++) { if(buc[i]%(i+1)) { flag=1; break; } buc[i+1]+=buc[i]/(i+1); } if(flag) cout<<"No"<<endl; else cout<<"Yes"<<endl; } return 0; }