穷举第一个字符串的所有子串,然后再判断其是否是其它字符串的子串。
然后注意输出字典序最小的答案。
判断枚举的子串是不是其它字符串子串时可以使用KMP,其实也可以直接暴力,因为题目数据范围不大。
学到一个技巧:可以使用memset(str,’\0’,sizeof(str)将字符数组清空。
还有一点需要注意的是在自己组合的字符串后面一定要记得加上字符串结束标志’\0’。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char str1[100],str2[100];
int next[100],n;
char ch[10][100];
void GetNext()
{
int j=0;
int len=strlen(str2+1);
next[1]=0;
for(int i=2;i<=len;i++)
{
while(j>0&&str2[j+1]!=str2[i])
j=next[j];
if(str2[j+1]==i)
j++;
next[i]=j;
}
}
int KMP()
{
int j=0;
int m=strlen(str2+1);
int len=strlen(str1+1);
for(int i=1;i<=len;i++)
{
while(j>0&&str2[j+1]!=str1[i])
j=next[j];
if(str2[j+1]==str1[i])
j++;
if(j==m)
return 1;
}
return 0;
}
void solve(char *ans)
{
for(int i=0;i<60;i++)
{
int cnt=1;
while(cnt<=60)
{
int ii;
for(int j=i;j<i+cnt;j++)
str2[j-i+1]=ch[1][j];
str2[cnt+1]=‘\0‘;///记得最后一位加上字符串结束标志
for(ii=2;ii<=n;ii++)
{
strcpy(str1+1,ch[ii]);
if(KMP()==0)
break;
}
if(ii>n)
{
if(strlen(str2+1)>strlen(ans+1))
strcpy(ans+1,str2+1);
else if (strlen(str2+1)==strlen(ans+1))
{
if(strcmp(ans+1,str2+1)>0)
strcpy(ans+1,str2+1);
}
cnt++;
}
else
break;
}
}
if(strlen(ans+1)<3)
printf("no significant commonalities\n");
else
printf("%s\n",ans+1);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
char ans[100];
///每次都必须要将ans数组清空,否则上次的答案会影响下次
memset(ans,‘\0‘,sizeof(ans));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%s",ch[i]);
solve(ans);
}
return 0;
}
时间: 2024-10-12 11:56:18