洛谷 P1709 [USACO5.5]隐藏口令Hidden Password
题目描述
有时候程序员有很奇怪的方法来隐藏他们的口令。Binny会选择一个字符串S(由N个小写字母组成,5<=N<=5,000,000),然后他把S顺时针绕成一个圈,每次取一个做开头字母并顺时针依次取字母而组成一个字符串。这样将得到一些字符串,他把它们排序后取出第一个字符串。把这个字符串的第一个字母在原字符串中的位置-1做为口令。
如字符串alabala,按操作的到7个字符串,排序后得:
aalabal
abalaal
alaalab
alabala
balaala
laalaba
labalaa
第一个字符串为aalabal,这个a在原字符串位置为7,7-1=6,则6为口令。
输入输出格式
输入格式:
第一行:一个数:N
第二行开始:字符串:S(每72个字符一个换行符)
输出格式:
一行,为得到的口令
输入输出样例
说明
题目满足:
30%的数据n<=10000
70%的数据n<=100000
100%的数据n<=5000000
时限 1s
题目翻译来自NOCOW。
USACO Training Section 5.5
//20170523新增数据四组
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 5000010 using namespace std; int n,len,ans,l,r; char s[MAXN],c; int main(){ scanf("%d",&n); n--; for(int i=0;i<=n;i++){ cin>>c; s[i]=c; } for(int i=1;i<=n;i++){ l=ans;r=i; while(s[l]==s[r]){ l++;r++; if(l>n) l=0; if(r>n) r=0; if(r==i) break; } if(s[l]>s[r]) ans=i; } printf("%d",ans); } /* 7 alabala */
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=5000110; int n; char s[maxn]; int Mini(int l){ int i,j,k; i=0;j=1;k=0; while(i<l&&j<l){ k=0; while(s[(i+k)%l]==s[(j+k)%l]&&k<l) k++; if(k==l) return (i<j)?i:j; if(s[(i+k)%l]>s[(j+k)%l]) i=i+k+1; else j=j+k+1; if(i==j) j++; } return (i<j)?i:j; } int main(){ cin>>n; for(int i=0;i<n;i++) cin>>s[i]; int l=Mini(n); cout<<l<<endl; return 0; }
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。