因為一直有事這道題又有點繁瑣, 所以寫了好多天今天才AC,不過1A還是很爽的。
思路還是很簡單的,對第一個主串列舉其所有子串,然後將每個子串都與其他的所以主串KMP匹配,如果是所有主串的公共子串則記錄 並選出最大的一個 注意這道題要字典序最小
程式碼:
#include "iostream"
using namespace std;
#define maxsize 80
char c[11][maxsize];
char substring[maxsize];
int next[11][maxsize];
char cans[maxsize];
void getnext(int n,int length)
{
int i=0,j=-1;
next[n][0]=-1;
while(i<length)
{
if (j==-1||c[n][i]==c[n][j])
{
i++;
j++;
next[n][i]=j;
}
else
{
j=next[n][j];
}
}
}
int KMP(int n,int length)
{
int i=0,j=0;
int length1=strlen(substring);
while (i<length&&j<length1)
{
if (j==-1||c[n][i]==substring[j])
{
i++;
j++;
}
else
{
j=next[n][j];
}
}
if (j>=length1)
{
return i-length1 ;
}
else
return -3;
}
int main()
{
int case1;
scanf("%d",&case1);
while (case1--)
{
int num;
scanf("%d",&num);
int i,j;
for(i=0;i<num;i++)
{
scanf("%s",c[i]);
int length=strlen(c[i]);
getnext(i,length);//計算每個字串的next
}
int length1=strlen(c[0]);
int tans=0;
//列舉從c[0]所有子串
for (i=2;i<length1;i++)//i表示子串長度
{
for (j=0;j<length1;j++)//j 表示子串第一個元素位置
{
substring[0]='\0';
strncpy(substring,c[0]+j,i+1);//得到一個子串
int flag=1;
int slen=strlen(substring);
//判斷子串在不在目標串中
for (int k=1;k<num;k++)
{
int temp=KMP(k,strlen(c[k]));
if (temp==-3)//說明這個子串不存在於c[k]
{
flag=0;
break;
}
}
if (flag==1)
{
if (tans==slen)
{
if (strcmp(cans,substring)>0)
{
tans=slen;
strcpy(cans,substring);
}
}
if (tans<slen)
{
tans=slen;
strcpy(cans,substring);
}
}
}
}
if (tans<3)
{
cout<<"no significant commonalities"<<endl;
}
else
cout<<cans<<endl;
}
}