http://acm.hdu.edu.cn/showproblem.php?pid=1238
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
之前写个是完全的暴力写的,因为数据很小,暴力也没关系,这次用了KMP,有点小题大做的感觉,不过刚刚学,就当练习了。
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; #define MOD 10000 #define N 210 char s[N][N]; int Next[N]; void FindNext(char b[]) { int i=0, j=-1, blen=strlen(b); Next[0] = -1; while(i<blen) { if(j==-1 || b[i]==b[j]) Next[++i] = ++j; else j = Next[j]; } } int KMP(char a[], char b[]) { int i=0, j=0; int alen=strlen(a), blen=strlen(b); FindNext(b); while(i<alen) { while(j==-1 || (a[i]==b[j] && i<alen && j<blen)) i++, j++; if(j==blen) return 1; j = Next[j]; } return 0; } int main() { int t; scanf("%d", &t); while(t--) { int i, j, k, n, MinLen=1000, len; char ss[N]; memset(s, 0, sizeof(s)); scanf("%d", &n); for(i=0; i<n; i++) { scanf("%s", s[i]); len = strlen(s[i]); if(len<MinLen) { MinLen = len; memset(ss, 0, sizeof(ss)); strcpy(ss, s[i]); } } char a[N], b[N]; int index=0; for(i=MinLen; i>0; i--) for(j=0; j<=MinLen-i; j++) { memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); strncpy(a, ss+j, i); strcpy(b, a); strrev(b); for(k=0; k<n; k++) { if(KMP(s[k], a)==0 && KMP(s[k], b)==0) break; } if(k==n) { index = i; i=-1, j=1000; } } if(index) printf("%d\n", index); else printf("0\n"); } return 0; }
勿忘初心