过几天一定要学后缀数组,题解上说可以用后缀数组解决
这里用,最小表示法,也算是一个模版了吧!
usaco 隐藏口令
<p style="margin-top: 0px; margin-bottom: 0.75em; font-size: 16px; line-height: 27.2px; text-indent: 1em; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif; background-color: rgb(254, 254, 254);">有时候程序员有很奇怪的方法来隐藏他们的口令。Billy"Hacker"Geits会选择一个字符串S(由L个小写字母组成,5<=L<=100,000),然后他把S顺时针绕成一个圈,每次取一个做开头字母并顺时针依次取字母而组成一个字符串。这样将得到一些字符串,他把它们排序后取出第一个字符串。把这个字符串的第一个字母在原字符串中的位置做为口令。</p><p style="margin-top: 0px; margin-bottom: 0.75em; font-size: 16px; line-height: 27.2px; text-indent: 1em; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif; background-color: rgb(254, 254, 254);">第一个字母所在的位置是0</p><p style="margin-top: 0px; margin-bottom: 0.75em; font-size: 16px; line-height: 27.2px; text-indent: 1em; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif; background-color: rgb(254, 254, 254);">如字符串alabala,按操作得到7个字符串,排序后得:</p><p style="margin-top: 0px; margin-bottom: 0.75em; font-size: 16px; line-height: 27.2px; text-indent: 1em; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif; background-color: rgb(254, 254, 254);">aalabal abalaal alaalab alabala balaala laalaba labalaa</p><p style="margin-top: 0px; margin-bottom: 0.75em; font-size: 16px; line-height: 27.2px; text-indent: 1em; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif; background-color: rgb(254, 254, 254);">第一个字符串为aalabal,这个a在原字符串位置为6,则6为口令。 当字符串相同时,输出编号最小的(即对于aaaa输出0)</p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; font-size: 14px; color: rgb(64, 50, 38); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; line-height: 24px;"><span style="margin: 0px; padding: 0px; font-family: 宋体;">初始时,i=0,j=1,分别以i,j,为起始点顺着i,j,往下比较直到找的str[i+k]!=str[j+k],然后分两种情况考虑:</span></p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; font-size: 14px; color: rgb(64, 50, 38); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; line-height: 24px;"><span style="margin: 0px; padding: 0px; font-family: 宋体;">1、 str[i+k]>str[j+k],i变成i=i+k+1,j不变,然后继续往下比较。(因为s【i——i+k-1】都比s【j】小)</span></p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; font-size: 14px; color: rgb(64, 50, 38); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; line-height: 24px;"><span style="margin: 0px; padding: 0px; font-family: 宋体;">2、 str[i+k]<str[j+k],j变成j=j+k+1,i不变,然后继续往下比较。{同上}</span></p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; font-size: 14px; color: rgb(64, 50, 38); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; line-height: 24px;"><span style="margin: 0px; padding: 0px; font-family: 宋体;">直到i或j大于串长,找较小者。</span></p>
#include<cstdio> #include<algorithm> #include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cmath> using namespace std; int n,len; char s[10000090]; int main() { scanf("%d",&len); scanf("%s",s); int i=0,j=1,k=0; while (i<len&&j<len&&k<len) { int t=s[(i+k)%len]-s[(j+k)%len]; if (t==0) k++; else { if (t>0) i=i+k+1; else j=j+k+1; if (i==j)j++; k=0; } } printf("%d",min(i,j)); return 0; }