数单词
时间限制:
2000 ms | 内存限制:
120000 KB
难度:
4
-
描述
-
为了能够顺利通过英语四六级考试,现在大家每天早上都会早起读英语。LYH本来以为自己在6月份的考试中可以通过六级,可是没想到,成绩出来以后,居然没有通过。所以他不得不付出更多的时间来学习英语。要想通过六级,最基本的要求就是词汇量。为了能够更快的记住一些陌生单词,LYH有时会找一些英语文章来读。今天早上,LYH又找了一篇文章。读之前,他突然萌生出一个想法:文章中哪些单词出现的次数最多呢?
-
输入
-
第一行输入一个整数T,表示有T组测试数据(1≤T≤200)。
对于每组测试数据,第一行输入一个整数n(1≤n≤150),表示LYH要查询的单词数量(有些单词可能会重复出现)。
接下来n行,每行输入一个单词,长度不大于100。
最后一行包含一个由小写字母组成的英语文章(字符串),长度不大于10^6。
输出
-
对于每组数据,第一行输出一个整数,表示单词出现的次数。
然后按照输入顺序,每行输出一个出现次数最多的单词。如果有重复出现的单词,把它们全部输出。
样例输入
-
2 3 good oo one goodafternooneveryone 1 to welcometotopcoder
样例输出
-
2 oo one 2
to
-
这一道题需要ac自动机的相关知识,可以参考这篇博客。
-
http://blog.youkuaiyun.com/niushuai666/article/details/7002823
-
#include <cstdio> #include <queue> #include <cstring> using namespace std; const int max_n = 1000700; int cnt; struct node{ node *fail; node *next[26]; int count; int id; node(){ memset(next,0,sizeof(next)); fail = NULL; count = 0; id = -1; } }; char word[200][108]; int keymap[200]; int ret[200]; char str[max_n]; int max_m; void insert(int pos,char *strk,node *root) { node *p = root; int i = 0; int index; while(strk[i]) { index = strk[i] - 'a'; if(p->next[index]==NULL) { p->next[index] = new node(); } p=p->next[index]; i++; } if(!p->count) { p->id = cnt++; p->count = 1; } keymap[pos] = p->id; } void build_ac_fail(node *root) { queue<node*> s; root->fail = NULL; s.push(root); while(!s.empty()) { node *tmp = s.front(); s.pop(); node *p = NULL; for(int i=0;i<26;i++) { if(tmp->next[i]) { if(tmp==root) tmp->next[i]->fail = root; else { p = tmp->fail; while(p) { if(p->next[i]) { tmp->next[i]->fail = p->next[i]; break; } p = p->fail; } if(!p) tmp->next[i]->fail = root; } s.push(tmp->next[i]); } } } } void query(node *root) { int i = 0; node *p = root; while(str[i]) { int index = str[i] - 'a'; while(!p->next[index]&&p!=root) { p = p->fail; } p = p->next[index]; p = (p==NULL)?root:p; node *tmp = p; while(tmp!=root) { if(tmp->count) { ret[tmp->id]++; if(ret[tmp->id]>max_m) { max_m = ret[tmp->id]; } } tmp = tmp->fail; } i++; } } int main() { int t,n,m; scanf("%d",&t); while(t--) { max_m = 0; cnt = 0; node *root = new node(); scanf("%d",&n); memset(ret,0,sizeof(ret)); for(int i = 0;i<n;i++) { scanf("%s",word[i]); insert(i,word[i],root); } build_ac_fail(root); scanf("%s",str); query(root); printf("%d\n",max_m); for(int i=0;i<n;i++) { if(ret[keymap[i]]==max_m) { printf("%s\n",word[i]); } } } }
-
第一行输入一个整数T,表示有T组测试数据(1≤T≤200)。