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;
}

其实不如跳过写下一题

原文地址:https://www.cnblogs.com/Run-dream/p/3871618.html