Asterix, Obelix and their temporary buddies Suffix and Prefix has finally found the Harmony temple. However, its doors were firmly locked and even Obelix had no luck opening them.
A little later they found a string s, carved on a rock below the temple's gates. Asterix supposed that that's the password that opens the temple and read the string aloud. However, nothing happened. Then Asterix supposed that a password is some substring t of the string s.
Prefix supposed that the substring t is the beginning of the string s; Suffix supposed that the substring t should be the end of the string s; and Obelix supposed that t should be located somewhere inside the string s, that is, t is neither its beginning, nor its end.
Asterix chose the substring t so as to please all his companions. Besides, from all acceptable variants Asterix chose the longest one (as Asterix loves long strings). When Asterix read the substring t aloud, the temple doors opened.
You know the string s. Find the substring t or determine that such substring does not exist and all that's been written above is just a nice legend.
You are given the string s whose length can vary from 1 to 106 (inclusive), consisting of small Latin letters.
Print the string t. If a suitable t string does not exist, then print "Just a legend" without the quotes.
input
fixprefixsuffix
output
fix
input
abcdabc
output
Just a legend
题目大意:
给你一个字符串,让你在里面找到一个最长的公共的前缀后缀,并且在 字符串中间也出现过一次的子串。
解题思路:
这个题KMP的next数组的理解还是要有的,next[i]表示在i之前,最长的 公共前缀后缀的长度。
所以说,我们首先要看看是否存在公共前缀后缀, 如果有,这只是保证了可能有解,因为我们还要看中间是否出现过,
这个时候,我们让i=next[i],继续看这个next[i]是否出现过,为什么呢? 因为你此往前移动是,就相当于产生了一个可能的答案,
但是我们需要中间 也出现过,所以就要判断这个next[i]值是否出现过,当出现过的就是答案。
1 #include <stdio.h> 2 #include <string.h> 3 4 char s[1000010]; 5 int next_[1000010],vis[1000010]; 6 7 void getnext() // 得到next数组 8 { 9 int i = 0, j = -1; 10 int len = strlen(s); 11 next_[0] = -1; 12 while (i < len){ 13 if (j == -1 || s[i] == s[j]) 14 next_[++ i] = ++ j; 15 else 16 j = next_[j]; 17 } 18 } 19 20 int main () 21 { 22 int i; 23 while (~scanf("%s",s)){ 24 int len = strlen(s); 25 getnext(); 26 memset(vis,0,sizeof(vis)); 27 for (i = 1; i < len; i ++) //将各个位置的最长前后缀标记 28 vis[next_[i]] = 1; 29 30 int j = len,flag = 0; 31 while (next_[j]>0){ 32 if (vis[next_[j]]){ 33 for (i = 0; i < next_[j]; i ++) 34 printf("%c",s[i]); 35 printf(" "); 36 flag = 1; break; 37 } 38 j = next_[j]; 39 } 40 if (!flag) 41 printf("Just a legend "); 42 } 43 return 0; 44 }