题目:
You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.
Input
The first line of the input file contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.
Output
There should be one line per test case containing the length of the largest string found.
Sample Input
2
3
ABCD
BCDFF
BRCD
2
rose
orchid
Sample Output
2
2
思路:
把第一个字符串,切分成各种组合
比如ABCD,切分为A,B,C,D,AB,BC,CD,ABC,BCD,ABCD,
然后将这些子串本身和翻转后的子串通过kmp判断是否在后面的所有字符串中都能匹配上,从中找出符合要求的最长子串。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int t,n,Next[110]; //next数组
void getNext(string s) //获取next数组的值(模板)
{
int len=s.size(),j=-1;
fill(Next,Next+110,0);
Next[0]=-1;
for(int i=1;i<len;i++)
{
while(j!=-1 && s[i]!=s[j+1]){
//直到匹配上或者到-1
j=Next[j];
}
if(s[i]==s[j+1]) j++;
Next[i]=j;
}
}
int kmp(string s1,string s2) //kmp
{
int len1=s1.size(),len2=s2.length(),j=-1;
getNext(s2); //先得到s2的next数组
for(int i=0;i<len1;i++)
{
while(j!=-1 && s1[i]!=s2[j+1]){
//直到匹配上或者到-1
j=Next[j];
}
if(s1[i]==s2[j+1]) j++;
if(j==len2-1) return 1; //匹配成功,返回true
}
return 0;
}
int main()
{
cin>>t;
while(t--)
{
string s[110];
int ans=0;
cin>>n;
for(int i=0;i<n;i++) cin>>s[i];
for(int i=0;i<s[0].size();i++) //以i开头
{
for(int j=1;j<=s[0].length();j++) //以j结尾
{
string t;
for(int k=i;k<j;k++) t+=s[0][k]; //从i遍历到j-1
if(t.size()) //子串存在
{
int flag=0; //标记是否有匹配不上的
for(int l=1;l<n;l++)
{
string tt=t;
reverse(tt.begin(),tt.end()); //翻转
if(!kmp(s[l],t) && !kmp(s[l],tt))
{
flag=1; //本身和翻转后都没匹配上,标记flag
break; //出现匹配不上,后面就不用继续了
}
}
if(!flag) if(t.size()>ans) ans=t.size(); //flag为0,都匹配上了,找出符合的最长子串
}
}
}
cout<<ans<<endl;
}
return 0;
}