CodeCraft-20 (Div. 2)
A. Grade Allocation
题意:给一组学生的最高成绩m,你可以任意加减每个学生的成绩,但要保证学生的平均成绩不变,给定一个a同学,求他可以变到的最高成绩。
分析:最高成绩已经确定,故学生a的成绩必须满足小于等于m,显然,若使平均成绩不变还要使学生a成绩最高,每次给除a以外同学成绩-1就使a同学成绩+1.
#include <iostream> #include <algorithm> #include <cmath> using namespace std; int t,n,x,a,b; int main() { scanf("%d",&t); while(t--) { scanf("%d%d%d%d",&n,&x,&a,&b); printf("%d\n",min(n-1,x+abs(b-a))); } }
B. String Modification
题意:给定一个长度为n的字符串,给定一个k,k代表一个区间的长度 1<=k<=n,每次对 s[i:i+k−1]的区间进行翻转,从字符串首开始直到i+k-1超过字符串长度为止。求能让字符串经过操作后字典序最小的k的最小值。
分析:我们看样例
输入:lfpbavjsm 输出:avjsmbpfl k=5 n=9 n-k=4
qwerty ertyqw k=3 n=6 n-k=3
qwer werq k=2 n=4 n-k=2
分析可知 前k-1个字符会被移动到字符串的末尾 且模拟推断可得 若n-k+1是奇数在末尾的k-1个字符顺序不变,偶数,则逆序。剩余 k~n部分字符串排到首位。故只需枚举k的长度进行比较就可以得出这道题的答案。(字符串比较字典序可直接用string类型作比较)
#include <iostream> #include <algorithm> #include <cstring> using namespace std; int t,n,ed=1; string ans; int main() { scanf("%d",&t); while(t--) { scanf("%d",&n); string s; cin>>s; ans=s; for(int k=2;k<=s.length();k++) { int kk=k-1; string x=s.substr(kk); string xx=s.substr(0,kk); if((n-k)%2==0) reverse(xx.begin(),xx.end()); x+=xx; if(x<ans){ ans=x; ed=k; } } cout<<ans<<endl; cout<<ed<<endl; } return 0; }
C. Primitive Primes
题意:给出了两个多项式的系数,求两个多项式相乘后问系数不能被p整除的幂的值
分析:
用a[i]表示第一个多项式的i次方的系数 b[i]表示第二个多项式的i次方的系数
c[i]表示相乘后i次方的乘积后的系数
c[0]=a[0]*b[0],
c[1]=a[0]*a[1]+b[0]*b[1],
c[2]=a[0]*b[2]+a[1]*b[1]+a[2]*b[0]
c[n]=a[0]*b[n]+a[1]*b[n-1]+a[2]*b[n-2]…+a[n-1]*b[1]+a[n]b[0]
我们分别找到第一个不可以被p整除的 a[i],b[j];
可知,对于a[i~i-1],b[i~i-1] 均可以被p整除
另 c为x^(i+j)的系数 则c=a[0]*b[i+j]+a[1]*b[i+j-1]+....+a[i+j]*b[0];
已知a[i~i-1],b[i~i-1] 均可以被p整除 故 对于他们之间任意积也可以被p整除
另除a[i]b[j]的式子为 pk(k为任意正整数) c=pk+a[i]b[j] %p!=0
故找出x的次幂 为i+j
#include <iostream> #include <algorithm> using namespace std; int n,m,p,x,y; const int N=1000100; int a[N]; int main() { scanf("%d%d%d",&n,&m,&p); for(int i=0;i<n;i++) { scanf("%d",&a[i]); if(a[i]%p!=0) x=i; } for(int i=0;i<m;i++) { scanf("%d",&a[i]); if(a[i]%p!=0) y=i; } printf("%d\n",x+y); }