给出一些字符串,找出最大满足条件的连续子串使之满足:在每一个字符串中都正序存在或逆序存在。输出最大长度。
Substrings
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8758 Accepted Submission(s): 4088
Problem Description
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
Author
Asia 2002, Tehran (Iran), Preliminary
Recommend
我的做法是把第一个字符串当作缝衣针,其他字符串先翻转,与自身组成两人一组。
对于每一组求出缝衣针中每个位置能匹配的最大长度。
之后求出所有非缝衣针字符集合中 缝衣针字符串每个位置能匹配的最大长度。
取所有位置的最大值。
/**==========================================
* This is a solution for ACM/ICPC problem
*
* @source:hdu 1238 Substrings
* @type: data_structrue KMP
* @author: wust_ysk
* @blog: http://blog.csdn.net/yskyskyer123
* @email: 2530094312@qq.com
*===========================================*/
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int INF =0x3f3f3f3f;
const int maxn=100 ;
//const int maxV=12 ;
string N[2*maxn+5];
string M;
string S;
int nex[maxn+5];
int len[2*maxn+5];
int len_S;
int len_M,n;
int dp[2*maxn][maxn+5];
void get(int ind)
{
int p=ind-1;
N[ind]="";
for(int i=len[p]-1;i>=0;i--)
{
N[ind]+=N[p][i];
}
}
void getnex()
{
nex[0]=nex[1]=0;
for(int i=1;i<len_M;i++)
{
int p=nex[i];
while(p&&M[p]!=M[i]) p=nex[p];
nex[i+1]= M[p]==M[i]? p+1:0;
}
}
void KMP(int ind,int delta)
{
int p=0;
for(int i=0;i<len[ind];i++)
{
while(p&&M[p]!=N[ind][i]) p=nex[p];
if(M[p]==N[ind][i])
{
dp[ind][delta+p]=max(dp[ind][delta+p],p+1 );
p++;
}
if(p==len_M) p=nex[p];
}
}
void getmax(int ind)
{
for(int i=0;i<len_S;i++)
{
dp[ind][i]=max(dp[ind][i],dp[ind+1][i]);
}
}
void work()
{
memset(dp,0,sizeof dp);
for(int st=0;st<len_S;st++)
{
M=S.substr(st,len_S);
len_M=len_S-st;
getnex();
for(int i=0;i<n;i++)
{
KMP( 2*i+1,st );
KMP( 2*i+2,st );
}
}
for(int i=0;i<n;i++)
{
getmax(2*i+1);
}
int ans=0;
memset(dp[0],0x3f,sizeof dp[0]);
for(int j=0;j<len_S;j++)
{
for(int i=1;i<=2*n-1;i+=2)
{
dp[0][j]=min(dp[0][j],dp[i][j] );
}
ans=max(ans,dp[0][j]);
}
printf("%d\n",ans);
}
int main()
{
int T;cin>>T;
while(T--)
{
cin>>n;
cin>>S;
len_S=S.length();
if(--n==0) {printf("%d\n",len_S);continue;}
for(int i=0;i<n;i++)
{
cin>>N[2*i+1];
len[2*i+2]=len[2*i+1]=N[2*i+1].length();
get(2*i+2);
}
work();
}
return 0;
}