题意:
给定字符串,要求找到一个最长的子串,
这个串既是前缀又是后缀且在字符串中间也出现过(中间意味着不是前缀也不是后缀)
如果存在输出该最长子串
否则输出Just a legend
Examples
Input
fixprefixsuffix
Output
fix
Input
abcdabc
Output
Just a legend
思路:
kmp的nt数组
nt[i]表示在i之前,最长的公共前缀后缀的长度。
要想有解,首先nt[len]必须是整数,否则表明不存在子串既是前缀又是后缀
接下来要判断是否在中间出现过
先标记1-(n-1)中出现过的全部nt[i],mark[nt[i]]=1
然后令temp=nt[n]
如果temp被标记过说明中间出现过,则找到答案了
否则temp=nt[temp]继续寻找解
详见代码
code:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxm=1e6+5;
char s[maxm];
int nt[maxm];
int mark[maxm];
int n;
void getnext(){
int i=0;
int j=nt[0]=-1;
while(i<n){
if(j==-1||s[i]==s[j]){
i++,j++;
nt[i]=j;
}else{
j=nt[j];
}
}
}
signed main(){
scanf("%s",s);
n=strlen(s);
getnext();
for(int i=1;i<n;i++){
mark[nt[i]]=1;
}
int temp=nt[n];
while(temp>0){
if(mark[temp]){
for(int i=0;i<temp;i++){
cout<<s[i];
}
cout<<endl;
return 0;
}else{
temp=nt[temp];
}
}
cout<<"Just a legend"<<endl;
return 0;
}