比賽鏈接: https://codeforces.com/contest/1316
A
題意:
給出n個同學的分數,和分數上限m,你可以修改1號同學的成績,問:在滿足n個同學的平均分不變 且 不超過分數上限的前提下,1號同學的成績最大是多少。
思路:
平均分不變,即n個同學的總分s不變,答案就是min(s,m)。
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m,s=0,x;
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i){
scanf("%d",&x);
s+=x;
}
printf("%d\n",min(m,s));
}
}
B
題意:
對於給出的字符串,輸出經過“操作”之後,字典序最小的字符串,並輸出“操作”的長度。
“操作”:對於長爲n的字符串s,長度爲k的操作是指:for i from 1 to n-k+1, reverse the substring s[i:i+k-1] of s。
思路:
先試幾個,找規律
對於“lfpbavjsm” (n=9)
k=5: avjsmbpfl
k=4: bavjsmlfp
對於“qwerty” (n=6)
k=3: ertyqw
可以發現:當k=i時,操作的結果就是先把substring[i:n]移到前面,然後,如果k和n同奇或同偶,就把前面的子串逆序拼接到後面,否則原封不動拼接到後面。
證明:翻轉操作執行的次數cnt=n-k+1, 如果cnt是偶數,那麼substring[1:k-1](被調到最後的前綴)相當於沒翻轉,如果cnt是奇數,那就是翻轉了。
所以,枚舉k from 1 to n,執行“操作”,找所有結果中字典序最小的即可。
代碼:
#include<bits/stdc++.h>
using namespace std;
string s;
int a[5005];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
cin>>s;
string ans=s;
int id=1;
for(int i=1;i<n;++i){
string s1=s.substr(0,i);
if((n-i)&1) reverse(s1.begin(),s1.end());
string s2=s.substr(i,n-i);
s2+=s1;
if(s2<ans){
ans=s2;
id=i+1;
}
}
cout<<ans<<endl<<id<<endl;
}
}
C
題意:
給兩個“本原多項式”和一個模數p,求多項式乘積的各項係數中不能整除p的係數對應的項的指數。
思路:
https://blog.csdn.net/qq_43563669/article/details/104666878
代碼:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,p,x,I,J;
scanf("%d%d%d",&n,&m,&p);
for(int i=0;i<n;++i) {scanf("%d",&x); if(x%p!=0) I=i;}
for(int i=0;i<m;++i) {scanf("%d",&x); if(x%p!=0) J=i;}
printf("%d\n",I+J);
}
拓展:
設是唯一分解整環上的多項式,如果,則稱爲上的一個本原多項式。
高斯引理:本原多項式的乘積還是本原多項式。
但是此題給出這個條件是爲什麼呢,我還不是太明白。
PS:還有用強力fft板子把這題過掉的,等我找到就貼上來。