Poj--3080Blue Jeans+KMP水题

来源:互联网 发布:淘宝现金券与代金券 编辑:程序博客网 时间:2024/05/21 07:02

题目链接:点击进入
大概的题意就是给n个字符串,然后让我们找出他们的最长的公共子串。
因为题目的数据比较小,我们可以枚举第一个串的所有子串,然后再用KMP判断一下这个子串是否出现在其它字符串中。

代码如下:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn=100;///x是模式串,m是长度,next是模式串对应的next数组void kmp_pre(char x[],int m,int next[]){    int  i,j;    j=next[0]=-1;    i=0;    while(i<m)    {        while(-1!=j&&x[i]!=x[j])          j=next[j];        next[++i]=++j;    }}int next[maxn];///x是模式串,y是主串bool KMP_count(char x[],int m,char y[],int n){    int i,j;    int ans=0;    kmp_pre(x,m,next);    i=j=0;    while(i<n)    {        while(-1!=j&&y[i]!=x[j])          j=next[j];        i++;j++;        if(j>=m)            return true;    }    return false;}char ans[maxn];char str[20][maxn];int main(){    int t;    freopen("in.txt","r",stdin);    scanf("%d",&t);    bool flag;    char x[maxn];    while(t--)    {        int n,k;        flag=false;        scanf("%d",&n);        for(int i=0;i<n;i++)          scanf("%s",str[i]);        int len=strlen(str[0]);        for(int i=0;i<len;i++)        {            int cnt=0;            x[cnt++]=str[0][i];          for(int j=i+1;j<len;j++)          {              x[cnt++]=str[0][j];              for(k=1;k<n;k++)              {                  if(!KMP_count(x,cnt,str[k],strlen(str[k])))                      break;              }              if(k>=n)              {                  if(!flag||cnt>strlen(ans))                  {                    x[cnt]='\0'; ///必须自己加上字符串结束标志                    strcpy(ans,x);                    flag=true;                  }                  else                  {                     x[cnt]='\0';                     if(cnt==strlen(ans)&&strcmp(x,ans)<0)                       strcpy(ans,x);                  }              }          }        }        if(!flag||strlen(ans)<3)        {            printf("no significant commonalities\n");            continue;        }        printf("%s\n",ans);    }  return 0;}
1 0