题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2896
输入的字符是所有可见的ASCII码(共有127个)所以要注意一下;
把结果存到一个数组中,然后输出;
要用c++交,G++会MLE的;
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; const int N = 1e4+10; int vis[N], a[N], cnt; char s[N]; struct node { int leaf; node *next[127],*fail; }; void AddTrie(char s[], node *root, int num) { node *p = root; for(int i=0; s[i]; i++) { int k = (int)s[i]; if(p->next[k]==NULL) p->next[k] = new node(); p = p->next[k]; } p->leaf = num; } void GetFail(node *root) { node *p, *q; queue<node*>Q; Q.push(root); while(Q.size()) { p = Q.front(); Q.pop(); for(int i=0; i<127; i++) { if(p->next[i]!=NULL) { q = p->fail; while(q!=NULL) { if(q->next[i]!=NULL) { p->next[i]->fail = q->next[i]; break; } q = q->fail; } if(q==NULL) p->next[i]->fail = root; Q.push(p->next[i]); } } } } void Query(char s[], node *root) { node *p = root, *q; for(int i=0; s[i]; i++) { int k = (int)s[i]; while(p->next[k] == NULL && p!=root)///如果匹配不成功,那么就走失败路径,沿着fail指针走,一直到找到或者跟结点为止; p = p->fail; p = p->next[k]; if(p==NULL) p = root; q = p; while(q!=root) { if(q->leaf && !vis[q->leaf]) { a[cnt++] = q->leaf; vis[q->leaf] = 1; } q = q->fail; } } } void FreeTrie(node *root) { node *p = root; for(int i=0; i<127; i++) { if(p->next[i]!=NULL) FreeTrie(p->next[i]); } free(p); } int main() { int n, m; while(scanf("%d", &n)!=EOF) { node *root = new node(); for(int i=1; i<=n; i++) { scanf("%s", s); AddTrie(s, root, i); } GetFail(root); scanf("%d", &m); int ans = 0; for(int i=1; i<=m; i++) { scanf("%s", s); memset(a, 0, sizeof(a)); memset(vis, 0, sizeof(vis)); cnt = 0; Query(s, root); if(cnt) { ans++; printf("web %d:", i); sort(a, a+cnt); for(int j=0; j<cnt; j++) printf(" %d", a[j]); printf("\n"); } } printf("total: %d\n", ans); FreeTrie(root); } return 0; }
时间: 2024-10-07 00:27:44