[恢]hdu 1238
2011-12-31 10:01:00
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1238
题意:给n个字符串,要求找字符串符合该串是所有给出的字符串或给出字符串的反串的子串的。求最大长度。
mark:先在输入的时候顺便存储所有串的反串,然后枚举第一个串的所有子串,最后kmp比较。
代码:
# include <stdio.h>
# include <string.h>
char ss[110][110] ;
char sr[110] ;
int next[110] = {-1} ;
int n ;
void getnext(char str[], int len)
{
int i, j = -1 ;
for (i = 1 ; i < len ; i++)
{
while (j != -1 && str[i] != str[j+1]) j = next[j] ;
if (str[i] == str[j+1]) j++ ;
next[i] = j ;
}
}
int kmp(char text[], char pattern[], int len1, int len2)
{
int i, j = -1 ;
getnext(pattern, len2) ;
for (i = 0 ; i < len1 ; i++)
{
while (j != -1 && text[i] != pattern[j+1]) j = next[j] ;
if (text[i] == pattern[j+1]) j++ ;
if (j == len2-1) return i-len2+1 ;
}
return -1 ;
}
int test (char str[])
{
int i, len1, len2 = strlen(str) ;
for (i = 1 ; i < n ; i++)
{
len1 = strlen(ss[i]) ;
if (kmp(ss[i], str, len1, len2) == -1) return 0 ;
}
return 1 ;
}
int gao()
{
int i, j, len = strlen(ss[0]) ;
char ch ;
for (i = 0 ; i < len ; i++)
sr[len-i-1] = ss[0][i] ;
sr[len] = '\0' ;
for (i = len ; i > 0 ; i--)//长度
{
for (j = 0 ; j < len-i+1 ; j++) //起始位置
{
ch = ss[0][j+i] ;
ss[0][j+i] = '\0' ;
if (test(ss[0]+j)) return i ;
ss[0][j+i] = ch ;
ch = sr[j+i] ;
sr[i+j] = '\0' ;
if (test(sr+j)) return i ;
sr[i+j] = ch ;
}
}
return 0 ;
}
int main ()
{
int i, T, ans ;
scanf ("%d", &T) ;
while (T--)
{
scanf ("%d", &n) ;
for (i = 0 ; i < n ; i++)
scanf ("%s", ss[i]) ;
ans = gao() ;
printf ("%d\n", ans) ;
}
return 0 ;
}