分析:有点需要注意的,输入的字符是所有可见的ASCII码,刚开始没看清一直以为是小写字母.............注意到这点后这题就是裸的自动机了。
代码如下:
==============================================================================================
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; const int MAXN = 1e6+7; const int MAXM = 130; const int oo = 1e9+37; char webStr[MAXN], s[MAXN]; int ans[MAXN], top;///保存某个网站被那些病毒侵占了 struct node { node *Fali, *next[MAXM]; int leaf, nweb;///已经被第n个web匹配过了 }; void Insert(node *root, char s[], 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 GetFial(node *root) { node *p = root, *temp; queue<node *> Q; for(int i=0; i<MAXM; i++) if(p->next[i]) { p->next[i]->Fali = root; Q.push(p->next[i]); } while(Q.size()) { p = Q.front(); Q.pop(); for(int i=0; i<MAXM; i++)if(p->next[i]) { temp = p->Fali; while(temp != NULL) { if(temp->next[i] != NULL) { p->next[i]->Fali = temp->next[i]; break; } temp = temp->Fali; } if(temp == NULL) p->next[i]->Fali = root; Q.push(p->next[i]); } } } void FreeTrie(node *root) { node *p = root; for(int i=0; i<MAXM; i++) { if(p->next[i]) FreeTrie(p->next[i]); } free(p); } void Query(node *root, int nweb) { node *p = root, *temp; for(int i=0; webStr[i]; i++) { int k = (int)webStr[i]; while(!p->next[k] && p!=root) p = p->Fali; if(!p->next[k])continue; temp = p = p->next[k]; while(temp != root && temp->nweb != nweb) { if(temp->leaf) ans[top++] = temp->leaf; temp->nweb = nweb; } } } int main() { int i, N, M; while(scanf("%d", &N) != EOF) { node *root = new node(); for(i=1; i<=N; i++) { scanf("%s", s); Insert(root, s, i); } GetFial(root); scanf("%d", &M); int total = 0; for(i=1; i<=M; i++) { scanf("%s", webStr); top = 0; Query(root, i); if(top) { sort(ans, ans+top); printf("web %d:", i); for(int j=0; j<top; j++) printf(" %d", ans[j]); printf(" "); total += 1; } } printf("total: %d ", total); FreeTrie(root); } return 0; }