http://poj.org/problem?id=3080
KMP解法
暴力枚举第一个串的一个子串 看是不是其他所有串的子串 kmp优化一下
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int nxtt[100];
char ch[20][100],pre[100];
int n;
void kmp(char *t,int lt)
{
int i,j;
nxtt[0]=-1;
i=0,j=-1;
while(i<lt)
{
if(j==-1||t[i]==t[j])
{
i++,j++;
nxtt[i]=j;
}
else j=nxtt[j];
}
}
int solveII(char *s,int ls,char *t,int lt)
{
int i,j;
i=0,j=0;
while(i<ls)
{
if(j==-1||s[i]==t[j])
{
i++,j++;
if(j==lt) return 1;
}
else j=nxtt[j];
}
return 0;
}
int solveI()
{
int res,i,lt,ls;
lt=strlen(pre);
kmp(pre,lt);
res=0;
for(i=1;i<n;i++) res+=solveII(ch[i],60,pre,lt);
return res;
}
int main()
{
int t,i,j,k,flag,res;
char ans[100];
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%s",ch[i]);
flag=0;
for(i=0;i<60;i++)
{
for(j=i+2;j<60;j++)
{
for(k=i;k<=j;k++) pre[k-i]=ch[0][k];
pre[k-i]='\0';
res=solveI();
if(res==n-1)
{
if(!flag)
{
flag=1;
memcpy(ans,pre,sizeof(pre));
}
else
{
if(strlen(ans)<strlen(pre)||(strlen(ans)==strlen(pre)&&strcmp(pre,ans)<0)) memcpy(ans,pre,sizeof(pre));
}
}
}
}
if(flag) printf("%s\n",ans);
else printf("no significant commonalities\n");
}
return 0;
}
EXKMP解法
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e2+10;
int nxtt[maxn],nxts[maxn];
char ch[maxn][maxn];
char tmp[maxn],ans[maxn];
int n,maxx;
void exkmp(char *t,int lt)
{
int i,j,p;
nxtt[0]=lt;
i=0;
while(i+1<lt&&t[i]==t[i+1]) i++;
nxtt[1]=i;
p=1;
for(i=2;i<lt;i++){
if(i+nxtt[i-p]<p+nxtt[p]) nxtt[i]=nxtt[i-p];
else{
j=max(0,p+nxtt[p]-i);
while(i+j<lt&&t[j]==t[i+j]) j++;
nxtt[i]=j;
p=i;
}
}
}
void solve(char *s,int ls,char *t,int lt)
{
int i,j,p;
i=0;
while(i<ls&&i<lt&&s[i]==t[i]) i++;
nxts[0]=i;
p=0;
for(i=1;i<ls;i++){
if(i+nxtt[i-p]<p+nxts[p]) nxts[i]=nxtt[i-p];
else{
j=max(0,p+nxts[p]-i);
while(i+j<ls&&j<lt&&s[i+j]==t[j]) j++;
nxts[i]=j;
p=i;
}
}
}
bool judge(int l,int r)
{
int i,j;
for(i=l;i<=r;i++) tmp[i-l]=ch[0][i];
tmp[r-l+1]='\0';
exkmp(tmp,r-l+1);
for(i=1;i<n;i++){
solve(ch[i],60,tmp,r-l+1);
for(j=0;j<60;j++){
if(nxts[j]==r-l+1) break;
}
if(j==60) return 0;
}
return 1;
}
int main()
{
int t,l,i;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%s",ch[i]);
maxx=0;
for(l=3;l<=60;l++){
for(i=0;i+l-1<60;i++){
if(judge(i,i+l-1)){
if(maxx<l||(maxx==l&&strcmp(ans,tmp)>0)){//
maxx=l;
strcpy(ans,tmp);
}
}
}
}
if(maxx<3) printf("no significant commonalities\n");
else printf("%s\n",ans);
}
return 0;
}