UVA1449 Dominating Patterns
UVA1449 Dominating Patterns
题目描述
有N个由小写字母组成的模式串以及一个文本串T。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串T中出现的次数最多。
输入输出格式
输入格式:
输入含多组数据。
每组数据的第一行为一个正整数N,表示共有N个模式串,1≤N≤150。
接下去N行,每行一个长度小于等于70的模式串。下一行是一个长度小于等于10^6 的文本串T.
输入结束标志为N=0。
输出格式:
对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。
输入输出样例
输入样例:
2
aba
bab
ababababac
6
beta
alpha
haha
delta
dede
tata
dedeltalphahahahototatalpha
0
输出样例:
4
aba
2
alpha
haha
挺有意思的的一道题,由于模板链(我是不是学生物学多了)模式串有很多,所以我们可以使用AC自动机来处理,然而模式串直接可能有重复,所以我们只需要在重复的模式串之间取一个就好了,为了方便,可以直接在trie树上统计每一个模式串最后出现的位置,然后就是AC自动机模板了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<map> 7 #include<queue> 8 #include<stack> 9 #include<algorithm> 10 #include<vector> 11 #define man 1000005 12 #define maxn 155 13 using namespace std; 14 15 inline int read() 16 { 17 char c=getchar(); 18 int res=0,x=1; 19 while(c<'0'||c>'9') 20 { 21 if(c=='-') 22 x=-1; 23 c=getchar(); 24 } 25 while(c>='0'&&c<='9') 26 { 27 res=res*10+(c-'0'); 28 c=getchar(); 29 } 30 return res*x; 31 } 32 33 int n,tot,ans; 34 int co[20005],f[20005],nt[20005],tree[20005][30]; 35 char b[155][75],a[man]; 36 queue<int>q; 37 38 void trie(char *s,int num) 39 { 40 int len=strlen(s),u=1; 41 for(register int i=0;i<len;i++) 42 { 43 int c=s[i]-'a'; 44 if(!tree[u][c]) 45 { 46 tree[u][c]=++tot; 47 } 48 u=tree[u][c]; 49 } 50 co[u]=num;//只需要统计每一个字符串的结尾就可以去重 51 } 52 53 void bfs() 54 { 55 for(register int i=0;i<26;i++) 56 tree[0][i]=1; 57 nt[1]=0;q.push(1); 58 while(q.size()) 59 { 60 int u=q.front();q.pop(); 61 for(register int i=0;i<=25;i++) 62 { 63 if(!tree[u][i]) 64 tree[u][i]=tree[nt[u]][i]; 65 else 66 { 67 int v=tree[u][i]; 68 q.push(v); 69 nt[v]=tree[nt[u]][i]; 70 } 71 } 72 } 73 } 74 75 void find(char *s) 76 { 77 int len=strlen(s),u=1,k; 78 for(register int i=0;i<len;i++) 79 { 80 int c=s[i]-'a'; 81 k=tree[u][c]; 82 while(k>1) 83 { 84 f[co[k]]++; 85 k=nt[k]; 86 } 87 u=tree[u][c]; 88 } 89 } 90 91 int main() 92 { 93 while(1) 94 { 95 n=read(); 96 if(n==0) break; 97 memset(co,0,sizeof(co)); 98 memset(f,0,sizeof(f)); 99 memset(nt,0,sizeof(nt)); 100 memset(tree,0,sizeof(tree)); 101 tot=1,ans=0; 102 for(register int i=1;i<=n;i++) 103 { 104 scanf("%s",b[i]); 105 trie(b[i],i); 106 } 107 scanf("%s",a); 108 bfs(); 109 find(a); 110 for(register int i=1;i<=n;i++) 111 ans=max(ans,f[i]); 112 printf("%d\n",ans); 113 for(register int i=1;i<=n;i++) 114 { 115 if(f[i]==ans) 116 printf("%s\n",b[i]); 117 } 118 } 119 return 0; 120 }