In fact, this question is easier than HDU virus attacks 1, but there is a trap that gets stuck to me: when you search for text, when you encounter letters that are not capital letters, then you need to start searching from the root node again, otherwise the answer will be wrong.
That's a trap.
Lesson: it seems that we need to think more deeply to find the traps. Otherwise, we will go through wa.
#include <stdio.h>#include <string.h>#include <queue>using std::queue;const int MAX_N = 1001;const int VIRUS_LEN = 51;const int TXT_LEN = 2000001;const int ARR_SIZE = 26;char Virus[MAX_N][VIRUS_LEN], txt[TXT_LEN];int IdNum[MAX_N];inline int getIndex(char a) { return a - 'A'; }struct Node{int n, num;Node *fail;Node *arr[ARR_SIZE];};Node pool[MAX_N*VIRUS_LEN], *Trie;int poolID;void clearNode(Node *rt){rt->n = rt->num = 0;rt->fail = NULL;memset(rt->arr, 0, sizeof(rt->arr));}void insert(char *w, int num){Node *pCrawl = Trie;for ( ; *w; w++){int id = getIndex(*w);if (!pCrawl->arr[id]){pCrawl->arr[id] = &pool[poolID++];clearNode(pCrawl->arr[id]);}pCrawl = pCrawl->arr[id];}pCrawl->n++;pCrawl->num = num;}void buildFail(){queue<Node *> qu;qu.push(Trie);while (!qu.empty()){Node *pCrawl = qu.front(); qu.pop();for (int i = 0; i < ARR_SIZE; i++){if (!pCrawl->arr[i]) continue;pCrawl->arr[i]->fail = Trie;Node *fail = pCrawl->fail;while (fail){if (fail->arr[i]){pCrawl->arr[i]->fail = fail->arr[i];break;}fail = fail->fail;}qu.push(pCrawl->arr[i]);}}}void search(){Node *pCrawl = Trie;for (char *p = txt; *p; p++){if (*p < 'A' || 'Z' < *p){pCrawl = Trie;continue;}int id = getIndex(*p);while (!pCrawl->arr[id] && pCrawl != Trie) pCrawl = pCrawl->fail;if (pCrawl->arr[id]){pCrawl = pCrawl->arr[id];for (Node *tmp = pCrawl; tmp && tmp->n; tmp = tmp->fail){if (tmp->n) IdNum[tmp->num]++;}}}}int main(){int n;Trie = &pool[0];while (scanf("%d", &n) != EOF){getchar();clearNode(Trie);poolID = 1;for (int i = 0; i < n; i++){gets(Virus[i]);insert(Virus[i], i);}buildFail();memset(IdNum, 0, sizeof(int) * n);gets(txt);search();for (int i = 0; i < n; i++){if (IdNum[i]) printf("%s: %d\n",Virus[i], IdNum[i]); }}return 0;}