【原题】
Sometimes the programmers have very strange ways of hiding their passwords. Billy "Hacker" Geits chooses a string S composed of L (5 <= L <= 100,000) lowercase letters (‘a‘..‘z‘) with length L. Then he makes and sorts all L-1 one-letter left cyclic shifts of the string. He then takes as a password one prefix of the lexicographically first of the obtained strings (including S).
For example consider the string "alabala". The sorted cyclic one-letter left shifts (including the initial string) are:
aalabal
abalaal
alaalab
alabala
balaala
laalaba
labalaa
Lexicographically, first string is ‘aalabal‘. The first letter of this string (‘a‘) is the ‘a‘ that was in position 6 in the initial string (counting the first letter in the string as position 0).
Write a program that, for given string S, finds the start position of the first letter of the sorted list of cyclic shifts of the string. If the first element appears more than once in the sorted list, then the program should output the smallest possible initial position.
7 alabala
6
【译题】
有时候程序员有很奇怪的方法来隐藏他们的口令。Billy"Hacker"Geits会选择一个字符串S(由L个小写字母组成,5<=L<=100,000),然后他把S顺时针绕成一个圈,每次取一个做开头字母并顺时针依次取字母而组成一个字符串。这样将得到一些字符串,他把它们排序后取出第一个字符串。把这个字符串的第一个字母在原字符串中的位置做为口令。
第一个字母所在的位置是0
如字符串alabala,按操作得到7个字符串,排序后得:
aalabal abalaal alaalab alabala balaala laalaba labalaa
第一个字符串为aalabal,这个a在原字符串位置为6,则6为口令。 当字符串相同时,输出编号最小的(即对于aaaa输出0)
PROGRAM NAME: hidden
INPUT FORMAT:
(file hidden.in)
INPUT FORMAT 第1行:一个数:L
第2..?行:字符串:S(每行72个字符,最后一行可能不够)
OUTPUT FORMAT:
(file hidden.out) 一行,为得到的口令
7 alabala
6
【分析】这道题看样子要用高级数据结构吧。但是我想暴力卡过去。第一次先扫一遍,把最小的字母位置记录下来。而且连续的一串只需记第一个。然后像滚动数组一样,一点一点比较当前数组中的后一位字母,直到只有1个位置剩下。 ------>>>>>>>但是,最后一个点超时了!!!
【代码1】
/* PROG:hidden ID:juan1973 LANG:C++ */ #include<stdio.h> #include<string> using namespace std; char s[200005],ch,chh; int n,i,cnt,tot,now,step,temp; int a[2][200005]; int main() { freopen("hidden.in","r",stdin); freopen("hidden.out","w",stdout); scanf("%d",&n); s[0]=getchar(); s[0]=‘!‘;ch=‘z‘+1; for (i=1;i<=n;i++) { chh=getchar(); while (chh<‘a‘||chh>‘z‘) chh=getchar(); s[i]=s[i+n]=chh; if (s[i]<ch) {ch=s[i];cnt=1;a[0][1]=i;} if (s[i]==ch&&s[i-1]!=s[i]) a[0][++cnt]=i; } while (cnt>1&&step<n-1) { tot=0;ch=‘z‘+1;step++;now^=1; for (i=1;i<=cnt;i++) { temp=a[now^1][i]; if (s[temp+step]<ch) {ch=s[temp+step];tot=1;a[now][1]=temp;} else if (s[temp+step]==ch) a[now][++tot]=temp; } cnt=tot; } printf("%d\n",a[now][1]-1); return 0; }
【代码2】
/* PROG:hidden ID:juan1973 LANG:C++ */ #include<stdio.h> #include<string> using namespace std; char s[200005],ch; int n,i,j,k; int main() { freopen("hidden.in","r",stdin); freopen("hidden.out","w",stdout); scanf("%d",&n); getchar(); for (i=0;i<n;i++) { ch=getchar(); if (ch>=‘a‘&&ch<=‘z‘) s[i]=s[i+n]=ch;else i--; } i=0;j=1; while (j<=n) { for (k=0;k<n;k++) if (s[i+k]!=s[j+k]) break; if (s[i+k]==s[j+k]) break; if (s[i+k]<s[j+k]) j=j+k+1;else i=i+k+1; if (i==j) j++; } printf("%d\n",i); return 0; }
usaco training 5.5.2 Hidden Password 题解,布布扣,bubuko.com
usaco training 5.5.2 Hidden Password 题解
原文:http://blog.csdn.net/jiangshibiao/article/details/21286703