POJ-3080 -求n个字符串最长公共子串-暴力枚举

来源:互联网 发布:配音的软件下载 编辑:程序博客网 时间:2024/05/16 14:58

。。。。数据太小,就直接用暴力n^3的做法了

以第一个串为主,枚举它的所有子串,看某个子串是否为其余所有字符串的 子串,如果是,则为公共子串


然后合法的子串里面找一个最长的,字典序最小的。


#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std; const int mod=1000000007;int min(int a,int b){return a<b?a:b;}int max(int a,int b){return a>b?a:b;}char tm[15][100];char first[100];char ans2[100][100];int cmp(char *s1,char* s2){return strcmp(s1,s2)<0;}int val[100];void getnext(char *s,int len){int i=1,j=0;val[1]=0;while(i<len){if (j==0||s[i]==s[j]){i++;j++;val[i]=j;}elsej=val[j];}}int kmp(char *s1,char *s2,int len1)//s1-子串,s2-字典{int len2=strlen(s2+1);int i=1,j=1;while(i<=len1&&j<=len2){if (i==0||s1[i]==s2[j]){i++,j++;}elsei=val[i];}if (i>len1)return i-len1;elsereturn -1;}struct node{int i,j;node(){}node(int a,int b){i=a;j=b;}};node ans[60*60*2];int main(){int t;cin>>t;while(t--){ int maxlen=0;int maxnum=0;int m;int i,j;cin>>m;scanf("%s",first+1);int len1=strlen(first+1);for (i=1;i<=m-1;i++){scanf("%s",tm[i]+1);} for (i=1;i<=len1;i++){for (j=i;j<=len1;j++){ if (j-i+1<maxlen) continue;char sub[100];int k;for (k=i;k<=j;k++)sub[k-i+1]=first[k];sub[j-i+2]=0;getnext(sub,j-i+1);int ret;int flag=0; for (int h=1;h<=m-1;h++){ ret=kmp(sub,tm[h],j-i+1);if (ret==-1){flag=1;break;}  }if (!flag){ans[++maxnum]=node(i,j);if (j-i+1>maxlen) maxlen=j-i+1; }}}  for (i=1;i<=maxnum;i++)  {  for(int k=ans[i].i;k<=ans[i].j;k++)  ans2[i][k-ans[i].i+1]=first[k];  ans2[i][ans[i].j-ans[i].i+2]=0;  }   int mini=maxnum;   int tmp_len=ans[maxnum].j-ans[maxnum].i+1;   for (i=1;i<=maxnum;i++)   {   if (ans[i].j-ans[i].i+1!=tmp_len ) continue;if (strcmp(ans2[i]+1,ans2[mini]+1)<0  )mini=i;   }   if (ans[mini].j-ans[mini].i+1<3)   printf("no significant commonalities\n");   elseprintf("%s\n",ans2[mini]+1);}return 0;}


0 0