POJ 1226 Substrings 暴力枚举+KMP算法
2012-07-07 11:28
399 查看
/*题意就是给你若干字符串,找出这些字符串中最大的相同字母个数,正逆序都可以。
想法是,因为必须是每个字符串中共有的部分,所以可以随便拿一个字符串来枚举他的子串。
我拿了a[1].然后枚举他不同长度的子串。
从大到小,如果KMP(子串,原串(2-n))||(KMP(逆序子串,原串(2-n)))成立的话,则该子串就是最大相同子串,因为是从大到小枚举的直接输出该串长度,结束。*/
考察KMP的应用以及子串的构造。枚举居然没超时。。
想法是,因为必须是每个字符串中共有的部分,所以可以随便拿一个字符串来枚举他的子串。
我拿了a[1].然后枚举他不同长度的子串。
从大到小,如果KMP(子串,原串(2-n))||(KMP(逆序子串,原串(2-n)))成立的话,则该子串就是最大相同子串,因为是从大到小枚举的直接输出该串长度,结束。*/
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cmath> #include <cstring> #include <queue> #include <set> #include <vector> #include <stack> #include <map> #include <iomanip> #define PI acos(-1.0) #define Max 2005 #define inf 1<<28 using namespace std; char a[Max][Max]; int next[Max],n; void findnext(char a[]) { int k=-1; int j=0; next[0]=-1; int l=strlen(a); while(j<l) { if(k==-1||a[k]==a[j]) { k++,j++; next[j]=k; } else k=next[k];//当前缀字符与后缀字符不相等时返回前一状态 } } int KMP(char a[],char b[]) { findnext(a); int posa=0,posb=0; int la=strlen(a),lb=strlen(b); while(posa<la&&posb<lb) { if(posa==-1||a[posa]==b[posb]) { posa++,posb++;//当匹配成功时,两个字符串各后移一个字符 } else posa=next[posa]; } if(posa<la)return 0;//匹配失败 //当匹配成功的时候posa的指针应该指向a字符串的最后一个字符+1处,也就是la处 else return 1;//匹配成功,若返回首地址可以写return posb-posa; } int main() { int i,j,k,l,m,T; char reva[Max],revb[Max]; cin>>T; while(T--) { int min_i=-1; int min_l=1000; cin>>n; for(i=1; i<=n; i++) { scanf("%s",a[i]);//网上看到一种写法就是直接在这一步中找出长度最小的原串,然后枚举该串。多一个比较的步骤,但是时间应该比我这个快 } l=strlen(a[1]); bool flag=0;//标记未找到最大子串 for(i=l;i>0;i--)//从最大子串开始枚举 { for(j=0;j<l-i+1;j++)//枚举的次数 { int count=0; for(k=j;k<=j+i-1;k++)//本次枚举的正序串 reva[count++]=a[1][k]; reva[count]='\0'; count=0; for(k=j+i-1;k>=j;k--)//本次枚举的逆序串 revb[count++]=a[1][k]; revb[count]='\0'; count=0; for(k=2;k<=n;k++)//是否与每一个原串都匹配 { if(KMP(reva,a[k])||KMP(revb,a[k])) count++; } if(count==n-1)//count=n-1则全部匹配,输出子串的长度即为答案 { flag=1; cout<<strlen(reva)<<endl; break; } } if(flag) break; } if(!flag) cout<<0<<endl; } return 0; }
考察KMP的应用以及子串的构造。枚举居然没超时。。
相关文章推荐
- poj1226 Substrings (应该用kmp,但是数据弱,暴力枚举就行了)
- POJ 1226 Substrings(KMP+枚举)
- POJ 1226 Substrings KMP暴力 或 后缀数组
- POJ 1207 求最大数链长度 暴力枚举数学题
- |poj 1226|后缀数组|二分|Substrings
- poj 1226|| hdu 1238 Substrings(KMP)
- poj 1166 The Clocks 暴力枚举
- POJ:2718 Smallest Difference(暴力枚举)
- POJ-----3279暴力枚举
- POJ 1226 后缀数组 或 KMP 或 暴力
- Counterfeit Dollar(poj1013暴力枚举)
- POJ1753 Flip Game(翻转问题且纯枚举暴力翻转)
- poj 1226 Substrings (后缀数组应用)
- kmp算法练习 poj 1226 poj 1961
- poj-1226 Substrings ***
- poj 1226 Substrings // poj 3450 Corporate Identidy KMP + 二分枚举
- POJ1543 水题 暴力枚举
- POJ-3080 -求n个字符串最长公共子串-暴力枚举
- poj 1226 Substrings
- POJ 1226 && HDU 1238 Substrings(kmp)