UVA1449 Dominating Patterns

UVA1449 Dominating Patterns

题目描述

N个由小写字母组成的模式串以及一个文本串T。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串T中出现的次数最多。

输入输出格式

输入格式:

输入含多组数据。

每组数据的第一行为一个正整数N,表示共有N个模式串,1N150。

接下去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 }
View Code

 

posted @ 2019-04-10 15:21  snowy2002  阅读(165)  评论(0编辑  收藏  举报