Substrings
Time limit:1000 ms |
|
Memory limit:10000 K |
Total submissions:10451 |
|
Accepted:3598 |
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 shoshould be one line per test case containing the length of the largest string found.
Sample Input
23ABCDBCDFFBRCD2roseorchid
Sample output
22
Give you n strings and find the smallest public continuous substring, but this can be reversed. For example, RO and or can match
Solution: the train of thought is very clear. The first string is used as the pattern string, and the next matching is decomposed and then reversed for next matching. The idea is to first locate the substring in sequence, and then find the relative position of its reverse string. For example, if the mode string abcdefg is used, I first put the reverse mode string in another array. The substring can be bcde (STA = 1, Len = 1 + 4), which is converted into edcb (STA = 7-1-4, Len = 7-1 ). in this way, we can see the rule. Decisive!
Topic address: substrings
AC code:
# Include <iostream> # include <cstring> # include <string> # include <cstdio> using namespace STD; int nextp [105], nexts [105], N; char A [105] [105]; char B [105]; // flip the mode string int lena0; // length of the mode string // my idea is to use the first string as the mode string, and then enumerate the length from large to small. Next matches void getnextp (int sta, int Len) // mode string {int I, j; Len = sta + Len; // The relative position is changed to the absolute position nextp [sta] = STA, nextp [sta + 1] = sta; for (I = sta + 1; I <Len; I ++) {J = nextp [I]; while (J! = Sta & A [0] [I]! = A [0] [J]) J = nextp [J]; if (a [0] [I] = A [0] [J]) nextp [I + 1] = J + 1; else nextp [I + 1] = sta ;}} void getnexts (INT STA, int Len) // The pattern string after flip {int I, j; STA = lena0-sta-len; // The Position of the substring to be converted to the position of B Len = sta + Len; nexts [sta] = STA, nexts [sta + 1] = sta; for (I = sta + 1; I <Len; I ++) {J = nexts [I]; while (J! = Sta & B [I]! = B [J]) J = nexts [J]; If (B [I] = B [J]) nexts [I + 1] = J + 1; else nexts [I + 1] = sta ;}} int KMP (int sta, int Len) {int I, j, k; int sta1 = sta; int sta2 = lena0-sta-len; int len1 = sta + Len; int len2 = sta2 + Len; For (k = 1; k <n; k ++) // The substring following the string matches with the substring of the first string {int flag = 0; j = sta1; for (I = 0; I <strlen (A [k]); I ++) {While (J! = Sta1 & A [k] [I]! = A [0] [J]) J = nextp [J]; if (a [k] [I] = A [0] [J]) J ++; if (j = len1) {flag = 1; break;} J = sta2; for (I = 0; I <strlen (A [k]); I ++) {While (J! = Sta2 & A [k] [I]! = B [J]) J = nexts [J]; if (a [k] [I] = B [J]) J ++; If (j = len2) {flag = 1; break; }}if (flag = 0) // if there is no match, 0 return 0;} return 1;} int main () is returned () {int I, j, T, L; scanf ("% d", & T); While (t --) {scanf ("% d", & N ); if (n = 0) break; for (I = 0; I <n; I ++) scanf ("% s", a [I]); lena0 = strlen (A [0]); for (I = 0; I <lena0; I ++) B [I] = A [0] [lena0-i-1]; B [lena0] = '\ 0'; int flag = 0; for (I = lena0; I> = 1; I --) // from the length lena0 start to enumerate down {int flag1 = 0; // whether the length of I exists for (j = 0; j <= lena0-i; j ++) // start position of mode string decomposition {getnextp (J, I); getnexts (J, I); If (KMP (J, I) {flag1 = 1; printf ("% d \ n", I); break ;}}if (flag1) {flag = 1; break ;}} if (flag = 0) puts ("0");} return 0 ;}