POJ3080

题目大意

求N个字符串的最长公共字串

题解

POJ1226做法一样。。。注意是字典序最小的。。。WA了一次

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define  MAXN 65
char p[MAXN],T[MAXN][MAXN];
int f[MAXN];
void getfail(char *p,int len)
{
      int j;
      f[0]=j=-1;
      for(int i=1;i<len;i++)
      {
          while(j>=0&&p[j+1]!=p[i]) j=f[j];
          if(p[j+1]==p[i]) j++;
          f[i]=j;
      }
}
bool find(char *s,int len,int n)
{
     getfail(s,len);
     for(int t=0;t<n;t++)
     { 
            int j=-1,lens=strlen(T[t]);
            bool flag=false;
            for(int i=0;i<lens;i++)
            {
                  while(j>=0&&s[j+1]!=T[t][i]) j=f[j];
                  if(s[j+1]==T[t][i]) j++;
                  if(j+1==len)
                  {
                         flag=true;
                         break;
                  }
            }
            if(!flag) return false;
     }
     return true;
}
int main()
{
    int cases;
    scanf("%d",&cases);
    while(cases--)
    {
        int n;
        scanf("%d",&n);
        char s[MAXN],temp[MAXN];
        temp[0]='';
        for(int i=0;i<n;i++) scanf("%s",T[i]);
        strcpy(s,T[0]);
        int len=strlen(s);
        for(int i=0;i<len;i++)
        {
            char ss[MAXN];
            ss[0]='';
            int l=i,r=len-1;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                bool flag=find(s+i,mid-i+1,n);
                if(flag)
                {
                    l=mid+1;
                    strncpy(ss,s+i,mid-i+1);
                    ss[mid-i+1]='';
                }
                else r=mid-1;
            }
            if(strlen(ss)>strlen(temp)||(strlen(ss)==strlen(temp)&&strcmp(ss,temp)==-1)) strcpy(temp,ss);
        }
        if(strlen(temp)>=3)
            printf("%s
",temp);
        else printf("no significant commonalities
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zjbztianya/p/3326630.html