您的位置:首页 > 运维架构

OpenJudge_P1746 子串(KMP)

2015-11-25 19:46 429 查看
总时间限制: 1000ms 内存限制: 65536kB

描述

现在有一些由英文字符组成的大小写敏感的字符串,你的任务是找到一个最长的字符串x,使得对于已经给出的字符串中的任意一个y,x或者是y的子串,或者x中的字符反序之后得到的新字符串是y的子串。

输入

输入的第一行是一个整数t (1 <= t <= 10),t表示测试数据的数目。对于每一组测试数据,第一行是一个整数n (1 <= n <= 100),表示已经给出n个字符串。接下来n行,每行给出一个长度在1和100之间的字符串。

输出

对于每一组测试数据,输出一行,给出题目中要求的字符串x的长度。

样例输入

2

3

ABCD

BCDFF

BRCD

2

rose

orchid

样例输出

2

2

作为OpenJudge上第一个A了这道题,并且一遍过的人我感到十分荣幸qwq,但是只是单纯为了练习一下KMP算法

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 105
int t,n,s,ll;bool flag;
int l
,next1
,next2
;      //next1正序  next2反序
char s1
,s2
,c

;        //s1正序 s2反序
inline int creat(int fr,int l){
memset(s1,0,sizeof(s1));memset(s2,0,sizeof(s2));
memset(next1,0,sizeof(next1));memset(next2,0,sizeof(next2));
for(int i=fr;i<fr+l;i++){
s1[i-fr]=c[s][i];s2[i-fr]=c[s][fr+l-1-i+fr];
}
int j=0,k=-1;next1[0]=-1;
while(j<l-1){
if(k==-1||s1[j]==s1[k]){
++j,++k;next1[j]=k;
}
else k=next1[k];
}
j=0;k=-1;next2[0]=-1;
while(j<l-1){
if(k==-1||s2[j]==s2[k]){
++j,++k;next2[j]=k;
}
else k=next2[k];
}
return 0;
}
inline int kmp(int k){
int i=0,j=0;
while(i<l[k]&&j<ll){
if(j==-1||c[k][i]==s1[j]){
++j,++i;
}
else j=next1[j];
}
if(j==ll) return 1;
i=0,j=0;
while(i<l[k]&&j<ll){
if(j==-1||c[k][i]==s2[j]){
++j,++i;
}
else j=next2[j];
}
if(j==ll) return 1;
return 0;
}
inline bool check(){
for(int i=1;i<=n;i++){
if(i!=s)
if(!kmp(i)) return false;
}
return true;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);getchar();s=1;flag=false;
memset(c,0,sizeof(c));memset(l,0,sizeof(l));
for(int i=1;i<=n;i++) {
scanf("%s",c[i]);l[i]=strlen(c[i]);
if(l[s]>l[i]) s=i;
}
for(ll=l[s];ll>0;ll--){
for(int j=0;j<=l[s]-ll;j++){
creat(j,ll);
if(check()) {flag=true;break;}
}
if(flag) {printf("%d\n",ll);break;}
}
if(!flag) printf("%d\n",0);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  KMP OpenJudge