poj 1226 Substrings

Substrings
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 10947 Accepted: 3799

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 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

Source

Tehran 2002 Preliminary

[Submit]   [Go Back]   [Status]   [Discuss]

/*=============================================================================
#     FileName: 1226.cpp
#         Desc: poj 1226
#       Author: zhuting
#        Email: [email protected]
#     HomePage: my.oschina.net/locusxt
#      Version: 0.0.1
#    CreatTime: 2013-12-21 16:55:33
#   LastChange: 2013-12-21 16:55:33
#      History:
=============================================================================*/
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <algorithm>
#define maxn 102
#define maxl 102

char str[maxn][maxl];
char tof[maxl];/*顺串*/
char tof2[maxl];/*逆串*/

int* get(char* a)/*计算next*/
{
	int len = strlen(a);
	if (len <= 0) return NULL;

	int * n = new int[len + 1];
	int j = 0, k = -1;
	n[0] = -1;

	while (j < len - 1)
	{
		while (k >= 0 && a[j] != a[k])
		{
			k = n[k];
		}
		++j, ++k;
		n[j] = k;
	}
	return n;
}

int fk(char * src, char * dest, int * n)/*kmp查找*/
{
	int j = 0, k = 0;
	int lens = strlen(src);
	int lend = strlen(dest);
	if (lens < lend) return -1;

	while (j < lens && k < lend)
	{
		if (k == -1 || src[j] == dest[k])
			++j, ++k;
		else
		{
			k = n[k];
		}
	}
	if (k >= lend)
		return j - lend;
	return -1;
}

void get_str(char * a, int st, int le)/*a数组,st处开始,长度为le*/
{
	strcpy(tof, a + st);
	tof[le] = '\0';
	return;
}

void get_rev(char * a, int st, int le)/*逆序串*/
{
	char * cur = a + st;
	tof2[le] = '\0';
	for (int i = le - 1; i >= 0; --i)
	{
		tof2[i] = *cur;
		++cur;
	}
	return;
}

bool find(int n)/*n为字符串组数*/
{
	int* ne = get(tof);
	int* ne2 = get(tof2);
	for (int i = 1; i < n; ++i)
	{
		int stat = fk(str[i], tof, ne);
		int stat2 = fk(str[i], tof2, ne2);
		if (stat == -1 && stat2 == -1)/*顺逆都找不到*/
			return 0;
	}
	return 1;
}

int main()
{
	int case_num = 0;
	scanf("%d", &case_num);
	int str_num = 0;
	for (int i = 0 ; i < case_num; ++i)
	{
		scanf("%d", &str_num);
		for (int j = 0; j < str_num; ++j)
		{
			scanf("%s", str[j]);
		}
		int len = strlen(str[0]);

		int ans = 0;
		bool is_find = 0;
		for (int j = len; j > 0; --j)/*查找的长度由长变短*/
		{
			if (is_find) break;
			for (int k = 0; k + j <= len; ++k)
			{
				get_str(str[0], k, j);
				get_rev(str[0], k, j);
				if (find(str_num))
				{
					ans = j;
					is_find = 1;
					break;
				}
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}




你可能感兴趣的:(poj)