标签:
http://acm.hdu.edu.cn/showproblem.php?pid=3374
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2045 Accepted Submission(s): 891
刚开始一直没明白是怎么回事,终于明白了吧,用暴力写了,明明知道时间超限,但我还是交了一次,果断的TLE,后来搜了搜,在看了许久后终于明白是怎么一回事,原来是用了两个指针, 用两个指针来动态比较,然后的然后就能求出最小字典串和最大字典串了,另外个数的问题其实只需要FindNext就可以求出来了,这个刚开始的时候是一直没想到,我只是想暴力求出来,然后发现自己忽略了这么好用的。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int maxn = 2000007; int Next[maxn], sum; char s1[maxn], s[maxn]; void FindNext(char S[]) { int i=0, j=-1; Next[0] = -1; int Slen = strlen(S); while(i<Slen) { if(j==-1 || S[i]==S[j]) Next[++i] = ++j; else j = Next[j]; } } int GetMin(char s[], int N) { int i=0, j=1; while(i<N && j<N) { int k=0; while(s[i+k]==s[j+k] && k<N) k++; if(k==N) break; if(s[i+k]<s[j+k]) { if(j+k>i) j += k+1; else j = i+1; } else { if(i+k>j) i += k+1; else i = j+1; } } return min(i, j); } int GetMax(char s[], int N) { int i=0, j=1; while(i<N && j<N) { int k=0; while(s[i+k]==s[j+k] && k<N) k++; if(k==N) break; if(s[i+k]>s[j+k]) { if(j+k>i) j += k+1; else j = i+1; } else { if(i+k>j) i += k+1; else i = j+1; } } return min(i, j); } int main() { while(scanf("%s", s1)!=EOF) { int N = strlen(s1); strcpy(s, s1); strcat(s, s1); FindNext(s); int circle = N - Next[N], time=1; if(N%circle==0) time = N / circle; printf("%d %d %d %d\n", GetMin(s, N)+1, time, GetMax(s, N)+1, time); } return 0; }
(kmp)String Problem -- hdu --3374
标签:
原文地址:http://www.cnblogs.com/YY56/p/4846489.html