最小表示法(双指针)
给定一个循环字符串S的一个周期
求S的字典序最小的周期
(比如 abc,bca,cab都是同一个循环字符串,这个循环字符串的最小表示是abc)
Input
有多组数据
每组数据只有一行
是只由小写字母组成的字符串
每行字符个数不超过20万
总字符个数不超过100万
Output
输出S的字典序最小的一个周期
SampleInput
aabaaaaabb bbbababa bbacccca baddd
SampleOutput
aaaaabbaab abababbb abbacccc adddb
朴素算法:
1 #include<stdio.h> 2 #include<string.h> 3 #define maxn 200005 4 ///环状串s的表示法p是否比表示法q的字典序小 5 int less(char* s, int p, int q) 6 { 7 int n = strlen(s); 8 int i; 9 for(i = 0; i < n; i++) 10 { 11 if(s[(p+i)%n] != s[(q+i)%n]) 12 return s[(p+i)%n] < s[(q+i)%n];///小为真,大为假 13 } 14 return 0; ///相等 15 } 16 int main() 17 { 18 int T; 19 char s[maxn]; 20 while(~scanf("%s", s)) 21 { 22 23 int ans = 0, i;///ans表示目前为止,字典序最小串在输入串中的起始位置,然后不断更新ans 24 int n = strlen(s); 25 for(i = 1; i < n; i++) 26 if(less(s, i, ans)) ans = i;///比较i与ans的大小,若真,将i的值给ans 27 for(i = 0; i < n; i++) 28 putchar(s[(i+ans)%n]);///求得ans的位置然后从ans的位置往后输出s 29 puts(""); 30 } 31 return 0; 32 }