HDU-1238

来源:互联网 发布:专家系统原理与编程 编辑:程序博客网 时间:2024/06/10 01:31

链接:

  http://acm.hdu.edu.cn/showproblem.php?pid=1238


题目:

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


题意:

  在给定的字符串或其反转串中找到最长公共子串。


思路:

  暴力KMP。


实现:

#include <cstdio>#include <cstring>using namespace std;const int maxn = 207;int jump[maxn];void process(char *p, int len) {    int i = 0, j = jump[0] = -1;    while(i < len) {        if(j < 0 || p[i] == p[j]) {            i++, j++;            jump[i] = (p[i] == p[j] ? jump[j] : j);        } else j = jump[j];    }}bool kmp(char *s, int ls, char *p, int lp) {    int i = 0, j = 0;    while(i < ls && j < lp) {        if(j < 0 || s[i] == p[j]) i++, j++;        else j = jump[j];    }    return j == lp;}char s[maxn][maxn];int main() {    int len[maxn], t, n; scanf("%d", &t);    while(t--) {        scanf("%d", &n);        for(int i=0 ; i<n ; i++) {            scanf("%s", s[i]), len[i] = int(strlen(s[i]));            for(int p = 0, q = len[i]-1 ; p <= q ; p++, q--)                s[i+n][q] = s[i][p], s[i+n][p] = s[i][q];        }        int tmp = len[0]+1, len0 = len[0];        bool flag = false;        while(!flag && --tmp > 0) {            for(int l = 0, r = tmp-1 ; r < len0 && !flag ; l++, r++) {                flag = true;                process(s[0]+l, r-l+1);                for(int i = 1 ; i < n && flag ; i++) {                    if(kmp(s[i], len[i], s[0]+l, tmp) || kmp(s[i+n], len[i], s[0]+l, tmp)) continue;                    flag = false;                }            }        }        printf("%d\n", tmp);    }    return 0;}
原创粉丝点击