這個題我想練一下kmp就沒用後綴數組做
後綴數組的思路也很簡單 鏈接所有串 然後二分答案就可以了
也可以暴力枚舉後綴 對每一個後綴用kmp找到最小公共前綴就可以
我算着複雜度是(200*4000*400)可能3s勉強能過...但是隻用了幾百ms 感覺數據出水了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
char s[4000+100][400];
int knext[4000+100];
void ekmp(char *s,int len){
int i = 0;
int j = -1;
knext[0] = -1;
while(i<len){
while(j!=-1&&s[i]!=s[j])j = knext[j];
knext[++i] = ++j;
}
}
int kmp_count(char *x,int n,char *y,int m){
int i,j;
i = 0;
j = 0;
ekmp(x,n);
int maxs = 0;
while(i<m){
while(j!=-1&&x[j]!=y[i])j = knext[j];
++i;++j;
if(j>=n){
return n;
}
maxs = max(maxs,j);
}
return maxs;
}
char ss[20000];
int lens[4000+100];
char res[20000];
int main(){
int n;
while(scanf("%d",&n)&&n){
int minn = 0x3f3f3f3f;
int k = -1;
for(int i = 0;i<n;++i){
scanf("%s",s[i]);
lens[i] = strlen(s[i]);
if(lens[i]<minn){
minn = lens[i];
k = i;
}
}
int maxs = 0;
int len2 = lens[k];
int st = 0;
int now_st = 0;
for(int j = 0;j<len2;++j){
st = j;
int cnt = 0;
for(int i = j;i<len2;++i){
ss[cnt++] = s[k][i];
}
ss[cnt] = '\0';
int len = cnt;
int minn1 = 0x3f3f3f3f;
for(int i = 0;i<n;++i){
int len1 = lens[i];
int index = kmp_count(ss,len,s[i],len1);
minn1 = min(minn1,index);
}
if(minn1>maxs){
maxs = minn1;
for(int h = 0;h<maxs;++h){
res[h] = ss[h];
}
res[maxs] = '\0';
}
else if(minn1==maxs&&strcmp(res,ss)>0){
for(int h = 0;h<maxs;++h){
res[h] = ss[h];
}
res[maxs] = '\0';
}
}
if(maxs){
printf("%s\n",res);
}
else{
cout<<"IDENTITY LOST"<<endl;
}
}
}
/*
3
abba
abcd
cdab
*
*/