题目:P3796
考前练板子,第一遍交RE了,原(jie)因(kou)是trie二位数组大小开反了……(我果然还是比较适合普及组)
//巨丑无比的代码 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; inline int read() { int f=1,x=0; char ch=getchar(); while(ch<'0' || ch>'9') {if(ch=='-') f=-1; ch=getchar();} while(ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,tot; char a[155][75],c[1000005]; int trie[15005][26],book[15005],f[15005],num[155]; queue <int> q; int ans=0; void make_trie(char *b,int x) { int len=strlen(b),i,u=0; for(i=0;i<len;i++) { int c=b[i]-'a'; if(!trie[u][c]) trie[u][c]=++tot; u=trie[u][c]; } book[u]=x; } void bfs() { int i; for(i=0;i<26;i++) if(trie[0][i]) q.push(trie[0][i]); while(!q.empty()) { int x=q.front(); q.pop(); for(i=0;i<26;i++) { if(!trie[x][i]) trie[x][i]=trie[f[x]][i]; else { f[trie[x][i]]=trie[f[x]][i]; q.push(trie[x][i]); } } } } void find_ac(char *b) { int u=0,len=strlen(b),i,k; for(i=0;i<len;i++) { int c=b[i]-'a'; u=trie[u][c]; for(k=u;k;k=f[k]) num[book[k]]++,ans+=book[k]; } } int main() { int i; while(1) { ans=0; tot=0; memset(f,0,sizeof(f)); memset(trie,0,sizeof(trie)); memset(book,0,sizeof(book)); memset(num,0,sizeof(num)); n=read(); if(!n) break; for(i=1;i<=n;i++) { scanf("%s",a[i]); make_trie(a[i],i); } bfs(); scanf("%s",c); find_ac(c); int maxn=-1; for(i=1;i<=n;i++) maxn=max(maxn,num[i]); printf("%d ",maxn); for(i=1;i<=n;i++) { if(num[i]==maxn) { printf("%s ",a[i]); } } } return 0; }