Seek the Name, Seek the Fame
| Time Limit: 2000MS |
|
Memory Limit: 65536K |
| Total Submissions: 9735 |
|
Accepted: 4670 |
Description The little cat is so famous, that many couples tramp over hill and dale to Byteland, and asked the little cat to give names to their newly-born babies. They seek the name, and at the same time seek the fame. In order to escape from such boring job, the innovative little cat works out an easy but fantastic algorithm: Step1. Connect the father's name and the mother's name, to a new string S. Step2. Find a proper prefix-suffix string of S (which is not only the prefix, but also the suffix of S). Example: Father='ala', Mother='la', we have S = 'ala'+'la' = 'alala'. Potential prefix-suffix strings of S are {'a', 'ala', 'alala'}. Given the string S, could you help the little cat to write a program to calculate the length of possible prefix-suffix strings of S? (He might thank you by giving your baby a name:) Input The input contains a number of test cases. Each test case occupies a single line that contains the string S described above. Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000. Output For each test case, output a single line with integer numbers in increasing order, denoting the possible length of the new baby's name.Sample Input ababcababababcababaaaaa Sample Output 2 4 9 181 2 3 4 5 Source POJ Monthly--2006.01.22,Zeyuan Zhu |
這個題目只要對KMP有一定理解就能做了,題目意思是求一個串的所有首碼與尾碼相同的串的長度
這個題目看見首先這個串就是一個,而且是最長的
然後就是對這個串求一次next求完之後就是輸出結果
結果就是輸出next[len]這個肯定不是本身最長的,然後不斷next next就OK了
至於為什麼這樣其實理解了KMP是不難發現的
就拿題目中的串來講解一下吧!
ababcababababcabab
0: -1 1: 0 2: 0 3: 1 4: 2 5: 0 6: 1 7: 2 8: 3 9: 4 10: 3 11: 4 12: 3 13: 4 14: 5 15: 6 16: 7 17: 8 18: 9
看18位置的next是9,那麼這個是一個答案,因為在位置18前面有9個字元是滿足題目的串
然後跳到9的這個位置,發現就是答案,其實結果已經很明顯了
18位置的next是9,那麼9位置的next值前面的next值個字元和18前面的幾個相同,而又與開始的
幾個相同,這樣就是尾碼與首碼相同,就是題目要求的答案了!
#include <iostream>#include <stdio.h>#include <string.h>using namespace std;char str[500000];int next[500000];int ans[500000];int pos;int get_next(int i,int j){next[0]=-1;while(str[i]){if(j==-1 || str[i]==str[j]){j++;i++;next[i]=j;}elsej=next[j];}return i;}int main(){int i,j,k;int len;while(scanf("%s",str)!=EOF){pos=0;len=get_next(0,-1);i=next[len];while(i!=-1){ans[pos++]=i;i=next[i];}for(i=pos-2;i>=0;i--)printf("%d ",ans[i]);printf("%d\n",len);}return 0;}