AC自动机板子如下, 以求匹配次数最多的串为例.
const int N = 1e6+10; int n, tot, ans; char text[N], p[155][100]; int last[N], val[N]; int ch[N][26], f[N], cnt[155], fa[155]; queue<int> q; void build() { f[0] = 0; REP(i,0,25) { int u = ch[0][i]; if (!u) continue; f[u] = 0, q.push(u), last[u] = 0; } while (q.size()) { int r = q.front(); q.pop(); REP(i,0,25) { int &u = ch[r][i], v=f[r]; if (u) q.push(u),f[u]=ch[v][i],last[u]=val[f[u]]?f[u]:last[f[u]]; else u=ch[v][i]; } } } void query(char *s) { int n = strlen(s), j = 0; REP(i,0,n-1) { j = ch[j][s[i]-'a']; int t = val[j]?j:last[j]; for (; t; t=last[t]) ++cnt[val[t]]; } } void ins(char *s, int id) { int u = 0, n = strlen(s); REP(i,0,n-1) { int c = s[i]-'a'; if (!ch[u][c]) { ch[u][c] = ++tot; val[tot] = 0; memset(ch[tot],0,sizeof ch[tot]); } u = ch[u][c]; } if (val[u]) fa[id] = u; else val[u] = id; } void init() { tot = 0; memset(cnt,0,sizeof cnt); memset(ch[0],0,sizeof ch[0]); REP(i,1,n) fa[i]=i; } void work() { init(); REP(i,1,n) scanf("%s", p[i]), ins(p[i], i); build(); scanf("%s", text); query(text); int ans = *max_element(cnt+1,cnt+1+n); printf("%d\n", ans); REP(i,1,n) if (cnt[fa[i]]==ans) puts(p[i]); } int main() { for (; scanf("%d", &n), n; ) work(); }