12.15
今日比赛,回来随手VP了一下CF #607 (Div2)
CF #607
- A:根据后缀判断三种语言。
直接大暴力就行了,没什么可说的。
#include<bits/stdc++.h>
using namespace std;
int main(){
int T;
scanf("%d",&T);
for(int z=1;z<=T;++z){
string s;
cin>>s;
int ed=s.size()-1;
if (s[ed-1]=='p'&&s[ed]=='o')
printf("FILIPINO
");
else if ((s[ed-3]=='d'&&s[ed-2]=='e'&&s[ed-1]=='s'&&s[ed]=='u')||(s[ed-3]=='m'&&s[ed-2]=='a'&&s[ed-1]=='s'&&s[ed]=='u'))
printf("JAPANESE
");
else
printf("KOREAN
");
}
return 0;
}
- B:给两个字符串s和c,s最多交换两个字符,问交换后是否能<c,输出<c的字符串。
思路:首先从头开始寻找s的不下降区间,到下降位置为止。之后向后找到最后一个最小的字母(及其位置),再从头开始找第一个比最小字母大的字母,交换这两者即可。
为什么要先找不下降区间?这样可以保证交换后可以更优。至少可以把下降位置的那两个交换。
#include<bits/stdc++.h>
using namespace std;
int main(){
int T;
scanf("%d",&T);
for(int z=1;z<=T;++z){
string s1,s2;
cin>>s1>>s2;
int p=1;
while(p<s1.size()&&s1[p-1]<=s1[p])
++p;
if (p==s1.size()){
if (s1<s2)
cout<<s1<<endl;
else
cout<<"---"<<endl;
continue;
}
int mnp=p;
for(int i=p+1;i<s1.size();++i)
if (s1[i]<=s1[mnp])
mnp=i;
int st=0;
while(s1[st]<=s1[mnp])
++st;
swap(s1[st],s1[mnp]);
if (s1<s2)
cout<<s1<<endl;
else
cout<<"---"<<endl;
}
return 0;
}
注意到s只有前x位是需要的。而且每一轮操作之后,s只会往后添加(或者不加),不会修改已有部分,所以在len(s)<x之前,暴力。之后的话就不用更新s了,只需要记录s长度的更新即可。
这题不能用string,常数太大会T。必须转成int数组,手动复制。
#include<bits/stdc++.h>
using namespace std;
const int P=1e9+7,M=1e6+10;
char s[505];
int num[M];
int main(){
int T;
scanf("%d",&T);
for(int z=1;z<=T;++z){
int x;
scanf("%d%s",&x,&s);
int l=0,lenn=strlen(s),cnt=0,cl,cr;
for(int i=0;i<lenn;++i)
num[++cnt]=s[i]-'0';
long long ans=lenn,lenc=0;
while(ans<x){
++l,cl=l+1,cr=cnt,ans+=(num[l]-1)*(cnt-l);
for(int i=1;i<=num[l]-1;++i){
if (cnt>x)
break;
for(int j=cl;j<=cr;++j){
if (cnt>x)
break;
num[++cnt]=num[j];
}
}
}
while(l<x)
++l,lenc=(ans-l+P)%P,ans=(ans+(num[l]-1)*lenc)%P;
printf("%lld
",ans);
}
return 0;
}
总结
之后几天先整理一下模板,做一些数据结构题,之后规划一下日后慢慢来的步骤,依次分别看哪些东西。
这赛季结束了,下赛季再见。