标签:
Description:
Input:
Output:
Sample Input:
Sample Output:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int N=1e6+10; char s[N*2], a[N]; ///s存放两个a字符串,供循环移位时需要 int Next[N], la; void Getnext() ///这个Next数组存放a的Next值 { int i = 0, j = -1; Next[0] = -1; while (i <= la) { if (j == -1 || a[i] == a[j]) { i++; j++; Next[i] = j; } else j = Next[j]; } } int GetMin() ///求出字典序最小的字符串最早出现的位置 { int i = 0, j = 1, k; ///这里i!=j,可以将s[i+k]和s[j+k]分别看做两个字符串的首字符(相当于在判断两个字符串的大小) while (i < la && j < la) { k = 0; ///k记录字符相等的个数 while (s[i+k] == s[j+k] && k < la) k++; if (k == la) break; ///若是la个字符都相等,那么可以确定两个字符串都是最小的,已经找到最小,停止查找 if (s[i+k] > s[j+k]) ///因为是求最小的,所以大的那个下标要后移,而小的值不变(类似求最小值,一直更新) { if (i+k > j) i = i+k+1; else i = j+1; } else { if (j+k > i) j = j+k+1; else j = i+1; } } return min(i, j); ///因为要最早,所以求最小值 } int GetMax() ///求出字典序最大的字符串最早出现的位置 { int i = 0, j = 1, k; while (i < la && j < la) { k = 0; while (s[i+k] == s[j+k] && k < la) k++; if (k == la) break; if (s[i+k] > s[j+k]) ///那么这里就是小的值向后移,大的值不变了 { if (j+k > i) j = j+k+1; else j = i+1; } else { if (i+k > j) i = i+k+1; else i = j+1; } } return min(i, j); } int main () { int x, Time, Miid, Maid; ///x记录循环节的长度,Time记录出现的次数 while (scanf("%s", a) != EOF) { strcpy(s, a); strcat(s, a); la = strlen(a); Getnext(); x = la - Next[la]; Time = la / x; ///可以得出最小值和最大值出现次数都为循环节的个数 Miid = GetMin(); Maid = GetMax(); printf("%d %d %d %d\n", Miid+1, Time, Maid+1, Time); ///因为下标都是从0开始的,所以要加1 } return 0; }
HDU 3374 String Problem(最大最小表示)
标签:
原文地址:http://www.cnblogs.com/syhandll/p/4864589.html