poj.3080

来源:互联网 发布:淘宝店铺手机端链接 编辑:程序博客网 时间:2024/06/09 01:03

这道题目的意思就是要求多个串的最长公共字串,直接用后缀树就可以解决,但还是用了暴搜,也可以解决,思路很简单,将第一个串reocrd【0】作为母串,对其每个字串进行枚举,长度为1的串,共60种,长度为2的串,共59种,依次类推,长度为60的串,共1种,对其中每个串进行判断,是否在其余m-1个串都中存在,若都存在则与已知的最长公共字串比较,否则,进行下一次循环。若长度较大或者长度相等并且字母较小,则将最长公共字串替换,否则进行下一次循环。这是最直接并且没有经过任何剪枝的思想,实际上我们可以这样进行剪枝:

将长度从大到小进行枚举,这样当一趟长度相同的所有可能字串都枚举了,如果其中存在某个串在其余m-1个中都存在,那么比该长度短的就不需要枚举了,直接剪掉,原因很明显,求最长公共字串。

下面是暴力搜索的代码:

#include <stdio.h>#include <stdlib.h>#include <cstring>#define Max 70using namespace std;char record[20][Max];char obj[Max];bool Is_over(const char *p,const char *q){int len1=strlen(p),len2=strlen(q);if(len1>len2)return 1;else if(len1==len2){for(int i=0;i<len1;i++)if(p[i]>q[i])return 0;else if(p[i]<q[i])return 1;}return 0;}int n,m;int main(){scanf("%d",&n);while(n--){int i,j;char *pivot;scanf("%d",&m);for(i=0;i<m;i++){getchar();scanf("%s",record[i]);}obj[0]='\0';for(i=60;i>=1;i--){bool trag=0;for(pivot=record[0];pivot<=record[0]+60-i;pivot++){char temp=*(pivot+i);*(pivot+i)='\0';bool tr=0;    for(j=1;j<=m-1;j++)   if(strstr(record[j],pivot)==NULL){   tr=1;       break;   }if(tr){*(pivot+i)=temp;continue;}trag=1;if(Is_over(pivot,obj))strcpy(obj,pivot);*(pivot+i)=temp;}if(trag)break;}int len=strlen(obj);if(len<3)printf("no significant commonalities\n");elseprintf("%s\n",obj);}return 0;}   


 

0 0