Problem C FZU 1901
Description
For each prefix with length P of a given string S,if
S[i]=S[i+P] for i in [0..SIZE(S)-p-1],
then the prefix is a “period” of S. We want to all the periodic prefixs.
Input
Input contains multiple cases.
The first line contains an integer T representing the number of cases. Then following T cases.
Each test case contains a string S (1 <= SIZE(S) <= 1000000),represents the title.S consists of lowercase ,uppercase letter.
Output
For each test case, first output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the number of periodic prefixs.Then output the lengths of the periodic prefixs in ascending order.
Sample Input
4 ooo acmacmacmacmacma fzufzufzuf stostootssto
Sample Output
Case #1: 3 1 2 3 Case #2: 6 3 6 9 12 15 16 Case #3: 4 3 6 9 10 Case #4: 2 9 12
自己写了一百分钟
没用KMP
主要是错了没发现
改了以后结果对了
只是超时
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 int main() 6 { 7 int T; 8 cin>>T; 9 int t = 0; 10 while(T--) 11 { 12 t++; 13 string s; 14 cin>>s; 15 int len =1; 16 int num =0; 17 int* length = new int[s.length()]; 18 while(len<s.length()) 19 { 20 string sub = s.substr(0,len); 21 int index = 0; 22 bool ok = true; 23 while(index<s.length()) 24 { 25 26 string temp = s.substr(index,len); 27 if(temp.length()<len) 28 { 29 sub = sub.substr(0,temp.length()); 30 } 31 if(sub.compare(temp)!=0) 32 { 33 ok = false; 34 35 break; 36 }else{ 37 index+=len; 38 } 39 } 40 41 42 if(ok==true) 43 { 44 length[num] = len; 45 num++; 46 } 47 len++; 48 } 49 num++; 50 cout<<"Case #"<<t<<": "<<num<<endl; 51 for(int i =0;i<num-1;i++) 52 { 53 cout<<length[i]<<" "; 54 } 55 cout<<s.length()<<endl; 56 } 57 return 0; 58 }
怎么才能不超时呢
我们考虑next(len),令t=next(len); next(len)有什么含义? str[1…t]=str[len-t+1…len] 那么,长度为len-next(len)的前缀显然是符合题意的。 接下来我们应该去考虑谁? t=next( next(len) ); t=next( next (next(len) ) ); 一直下去直到t=0,每个符合题意的前缀长是len-t。
没想到
我想的是从小到大
忘记了递归
#include <iostream> #include<string> using namespace std; #define N 1000100 int a[N],next[N]; int m; string s; void getNext(){ next[0]=0; next[1]=0; for(int i=1;i<m;i++){ int j=next[i]; while(s.at(j)!=s.at(i)&&j) j=next[j]; if(s.at(j)==s.at(i)) next[i+1]=j+1; else next[i+1]=0; } } int main() { int T,count; cin.sync_with_stdio(false); cin>>T; for(int i=1;i<=T;i++){ cin>>s; m=s.length(),count=0; int t=m; getNext(); while(next[m]) { a[count++]=t-next[m]; m=next[m]; } cout<<"Case #"<<i<<": "<<count+1<<endl; for(int i=0;i<count;i++) cout<<a[i]<<' '; cout<<t<<endl; } return 0; }
其实不如跳过写下一题