Question: give you a maximum of 100 strings. Find the longest and more than half of the string's public substrings. If there are multiple strings, output them in Lexicographic Order.
Train of Thought: First combine the strings, add a character that has not appeared before in the middle, and then find the suffix. Then, the longest Public String is obtained based on the h array and the sa array.
# Include <stdio. h> # include <string. h >#include <algorithm> using std: sort; # define V 220000int r [V], sa [V], h [V], a [V], B [V], X [V], Y [V]; int acl [120], len [110], tot, mark [V], mark_len, be [V], m [110], max_len; char s [V], out1 [V], out2 [V]; void calh (int n) {int I, j, k = 0; for (I = 1; I <= n; I ++) r [sa [I] = I; for (I = 0; I <n; h [r [I ++] = k) for (k? K --: 0, j = sa [r [I]-1]; a [I + k] = a [j + k]; k ++ );} bool cmp (int * r, int a, int B, int le) {return (r [a] = r [B] & r [a + le] = r [B + le]);} void suffix (int n, int m = 128) {int I, j, * x = X, * y = Y, * t, p; for (I = 0; I <m; I ++) B [I] = 0; for (I = 0; I <n; I ++) B [x [I] = a [I] ++; for (I = 1; I <m; I ++) B [I] + = B [I-1]; for (I = n-1; I> = 0; I --) sa [-- B [x [I] = I; for (j = 1, p = 1; p <n; m = p, j <= 1) {p = 0; for (I = n-j; I <n; I ++) y [p ++] = I; for (I = 0; I <n; I ++) if (sa [I]> = j) y [p ++] = sa [I]-j; For (I = 0; I <m; I ++) B [I] = 0; for (I = 0; I <n; I ++) B [x [y [I] + +; for (I = 1; I <m; I ++) B [I] + = B [I-1]; for (I = n-1; I> = 0; I --) sa [-- B [x [y [I] = y [I]; for (t = x, x = y, y = t, x [sa [0] = 0, I = 1, p = 1; I <n; I ++) x [sa [I] = cmp (y, sa [I-1], sa [I], j )? P-1: p ++;} calh (n-1);} void judge (int n) // pre-process the string of each sa {int I, j, k; for (I = 1; I <= n; I ++) {for (j = 1; j <= tot; j ++) {if (sa [I] = len [j]) {be [I] = 0; break;} if (sa [I] <len [j]) {be [I] = j; break ;}}} int mm [110]; int getmin (int s) // obtain the longest length of the Public String by sorting {for (int I = 1; I <= tot; I ++) mm [I] = m [I]; sort (mm + 1, mm + 1 + tot); return mm [tot + 1-s];} void solve (int n) {int cou = tot/2 + 1, cur = 0, cur_len = 0, I, j; // cou indicates the number of required strings. cur indicates the number of strings of the current substring, cu R_len indicates the length of the current substring judge (n); memset (m, 0, sizeof (m )); // m indicates the length of the substring contained in each string for (I = 1; I <= n; I ++) {for (j = 1; j <= tot; j ++) if (m [j]> h [I]) // update mi m [j] = h [I]; if (h [I] <max_len) {cur = 0; continue;} if (h [I]> m [be [I]) {if (m [be [I] = 0 | m [be [I] <max_len) cur ++; m [be [I] = h [I];} if (h [I]> m [be [I-1]) {if (m [be [I-1] = 0 | m [be [I-1] <max_len) cur ++; m [be [I-1] = h [I];} if (cur> = cou) {cur_len = getmin (cou); if (cur_len> max_len) {mark_len = 1; m Ark [0] = sa [I]; max_len = cur_len;} else if (cur_len = max_len) mark [mark_len ++] = sa [I] ;}} int main () {int I, j, k, t, n; for (I = 1; I <= 96; I ++) acl [I] = I; for (I = 97; I <= 110; I ++) acl [I] = I + 26; while (scanf ("% d", & t )! =-1 & t) {len [0] =-1; for (I = 1; I <= t; I ++) {scanf ("% s ", s + len [I-1] + 1); len [I] = strlen (s); s [len [I] = acl [I];} s [len [t] = 0; n = strlen (s); for (I = 0; I <n; I ++) a [I] = s [I]; a [n] = 0; suffix (n + 1); mark_len = 0; max_len = 0; tot = t; solve (n); if (max_len = 0) printf ("? \ N "); else {strcpy (out1, s + mark [0]); out1 [max_len] = 0; puts (out1); for (I = 1; I <mark_len; I ++) {strcpy (out2, s + mark [I]); out2 [max_len] = 0; if (strcmp (out1, out2) = 0) continue; strcpy (out1, out2); puts (out1) ;}puts ("") ;}} return 0 ;}