POJ 3080 Blue Jeans (KMP)
求出公共子序列 要求最长 字典序最小
枚举第一串的所有子串 然后对每一个串做KMP。找到目标子串
学会了 strncpy函数的使用 我已可入灵魂
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; char str[20][70]; char tmp[70],ans[70]; int f[70]; int n; void getfail(char *P) { int m=strlen(P); f[0]=0;f[1]=0; for(int i=1;i<m;i++) { int j=f[i]; while(j&&P[i]!=P[j])j=f[j]; f[i+1]=P[i]==P[j]?j+1:0; } } bool find(char *P,char *T) { int n=strlen(T); int m=strlen(P); getfail(P); int j=0; for(int i=0;i<n;i++) { while(j&&P[j]!=T[i])j=f[j]; if(P[j]==T[i])j++; if(j==m)return true;//printf("%d\n",i-m+1); } return false; } bool work(char *tmp,int l)//l : tmp len: ans { for(int i=2;i<=n;i++) { if(!find(tmp,str[i]))return false; } int len=strlen(ans); if(l>len)strcpy(ans,tmp);//最长 else if(l==len && strcmp(tmp,ans)<0)strcpy(ans,tmp);//字典序最小 return true; } int main() { int CASE; scanf("%d",&CASE); while(CASE--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",str[i]); memset(ans,0,sizeof(ans)); memset(tmp,0,sizeof(tmp)); int len=strlen(str[1]); for(int i=1;i<=len;i++) { for(int j=0;j<len-i+1;j++) { strncpy(tmp,str[1]+j,i); work(tmp,i); } } if(strlen(ans)>=3)printf("%s\n",ans);//题目中说要至少3个长度 else printf("no significant commonalities\n"); } return 0; }