题目大意:求一组字符串的最长子串,子串包括逆串匹配
解题思路:选一个最短字符串,枚举其子串,跟其他字符串用kmp正匹配和逆匹配
注意没有子串匹配的情况。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <climits>
using namespace std;
const int maxn = 102;
char str[maxn][maxn];
int slen[maxn];
int next[maxn], t, n;
void compute_next(int index);
bool kmp(int k, int index, int st, int ed, bool flag);
int main()
{
scanf("%d", &t);
while(t-- != 0)
{
int index = -1, minv = INT_MAX;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%s", str[i]);
slen[i] = strlen(str[i]);
if(minv > slen[i])
{
minv = slen[i];
index = i;
}
}
compute_next(index);
int ans = INT_MIN;
for(int i = 0; i < slen[index]; i++)
{
for(int j = slen[index] - 1; j >= i; j--)
{
bool flag = true;
for(int k = 0; k < n; k++)
{
if(k == index)
continue;
flag &= (kmp(k, index, i, j, true) || kmp(k, index, i, j, false));
if(!flag)
break;
}
if(flag)
{
ans = max(ans, j - i + 1);
break;
}
}
}
if(INT_MIN == ans)
printf("0\n");
else
printf("%d\n", ans);
}
return 0;
}
void compute_next(int index)
{
next[0] = -1;
int i = -1, j = 0;
while(j <= slen[index])
{
if(i == -1 || str[index][i] == str[index][j])
{
i++; j++;
next[j] = i;
}
else
i = next[i];
}
}
bool kmp(int k, int index, int st, int ed, bool flag)
{
int i, j;
if(flag)
{
i = 0; j = st;
while(i < slen[k] && j <= ed)
{
if(j < st || str[k][i] == str[index][j])
{
i++;
if(j < st)
j = st;
else
j++;
}
else
j = next[j];
}
if(j > ed)
return true;
}
else
{
i = slen[k] - 1; j = st;
while(i >= 0 && j <= ed)
{
if(j < st || str[k][i] == str[index][j])
{
i--;
if(j < st)
j = st;
else
j++;
}
else
j = next[j];
}
if(j > ed)
return true;
}
return false;
}