题目描述 Description
有时候程序员有很奇怪的方法来隐藏他们的口令。Billy”Hacker”Geits会选择一个字符串S(由L个小写字母组成,5<=L<=100,000),然后他把S顺时针绕成一个圈,每次取一个做开头字母并顺时针依次取字母而组成一个字符串。这样将得到一些字符串,他把它们排序后取出第一个字符串。把这个字符串的第一个字母在原字符串中的位置做为口令。
第一个字母所在的位置是0
如字符串alabala,按操作的到7个字符串,排序后得:
aalabal abalaal alaalab alabala balaala laalaba labalaa
第一个字符串为aalabal,这个a在原字符串位置为6,则6为口令。
输入描述 Input Description
第一行:一个数:L
第二行:字符串:S
输出描述 Output Description
一行,为得到的口令
样例输入 Sample Input
7
alabala
样例输出 Sample Output
6
【2017.10.19考试T3】
这个题应用字符串最小表示法。
注意边界的判断。
①:k不能超过l;
②:k=l时返回i,j中较小的一个(好像只能返回i,在洛谷只返回j会wa两个点,一般情况下j在i的后面)
③:i=j时j++;
④:复制一遍原来的字符数组
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=10000000+10;
char s[maxn];
int l;
int Minn(char *s,int l)//int Minn(int l)
{
int i=0,j=1,k=0;
while(i<l&&j<l)
{
k=0;
while(s[i+k]==s[j+k]&&k<l) k++;//注意条件要写全~
if(k==l) return min(i,j);
if(s[i+k]>s[j+k]) i=i+k+1;
else j=j+k+1;
if(i==j) j++;
}
if(i>=l) return j;
else return i;
}
int main()
{
scanf("%d",&l);
for(int i=0;i<l;i++)
{
cin>>s[i];
s[i+l]=s[i];
}
cout<<Minn(s,l)<<'\n';//cout<<Minn(l)<<'\n';
return 0;
}
用scanf读入时codevs全WA,原因可能是数据里有多余的空格和回车,所以读字符的时候如果不是特别必要就用cin把。。