Time Limit: 5000MS | Memory Limit: 65536K | |||
Total Submissions: 8153 | Accepted: 3086 | Special Judge |
Description
Input
Output
Sample Input
20 20 10 QWSPILAATIRAGRAMYKEI AGTRCLQAXLPOIJLFVBUQ TQTKAZXVMRWALEMAPKCW LIEACNKAZXKPOTPIZCEO FGKLSTCBTROPICALBLBC JEWHJEEWSMLPOEKORORA LUPQWRNJOAAGJKMUSJAE KRQEIOLOAOQPRTVILCBZ QOPUCAJSPPOUTMTSLPSF LPOUYTRFGMMLKIUISXSW WAHCPOIYTGAKLMNAHBVA EIAKHPLBGSMCLOGNGJML LDTIKENVCSWQAZUAOEAL HOPLPGEJKMNUTIIORMNC LOIUFTGSQACAXMOPBEIO QOASDHOPEPNBUYUYOBXB IONIAELOJHSWASMOUTRK HPOIYTJPLNAQWDRIBITG LPOINUYMRTEMPTMLMNBO PAFCOPLHAVAIANALBPFS MARGARITA ALEMA BARBECUE TROPICAL SUPREMA LOUISIANA CHEESEHAM EUROPA HAVAIANA CAMPONESA
Sample Output
0 15 G 2 11 C 7 18 A 4 8 C 16 13 B 4 15 E 10 3 D 5 1 E 19 7 C 11 11 H
Source
本题打算用确定性有限状态自动机,不知怎么出错了,看了别人的代码才发现普通字典树+深搜亦可以
粘贴大牛代码
#include <iostream> #include<string> #include<cstring> #include<cstdio> #include <vector> #include <queue> using namespace std; #define LETTERS 26 int nNodesCount = 0; struct CNode { CNode * pChilds[LETTERS]; CNode * pPrev; //前缀指针 bool bBadNode; //是否是危险节点 void Init() { memset(pChilds,0,sizeof(pChilds)); bBadNode = false; pPrev = NULL; } }; CNode Tree[500]; //10个模式串,每个10个字符,每个字符一个节点,也只要100个节点 void Insert( CNode * pRoot, char * s) {//将模式串s插入trie树 for( int i = 0; s[i]; i ++ ) { if( pRoot->pChilds[s[i]-'A'] == NULL) { pRoot->pChilds[s[i]-'A'] = Tree + nNodesCount; nNodesCount ++; // printf("%d %d\n",s[i]-'A',nNodesCount); } pRoot = pRoot->pChilds[s[i]-'A']; } pRoot-> bBadNode = true; } void BuildDfa( ) { //在trie树上加前缀指针 for( int i = 0;i < LETTERS ;i ++ ) Tree[0].pChilds[i] = Tree + 1; Tree[0].pPrev = NULL; Tree[1].pPrev = Tree; deque<CNode * > q; q.push_back(Tree+1); while( ! q.empty() ) { CNode * pRoot = q.front(); q.pop_front(); for( int i = 0; i < LETTERS ; i ++ ) { CNode * p = pRoot->pChilds[i]; if( p) { CNode * pPrev = pRoot->pPrev; while( pPrev ) { if( pPrev->pChilds[i] ) { p->pPrev = pPrev->pChilds[i]; if( p->pPrev-> bBadNode) p-> bBadNode = true; //自己的pPrev指向的节点是危险节点,则自己也是危险节点 break; } else pPrev = pPrev->pPrev; } q.push_back(p); } } } //对应于while( ! q.empty() ) } bool SearchDfa(char * s) {//返回值为true则说明包含模式串 CNode * p = Tree + 1; for( int i = 0; s[i] ;i ++ ) { while(true) { if( p->pChilds[s[i]-'A']) { p = p->pChilds[s[i]-'A']; if( p-> bBadNode) return true; break; } else p = p->pPrev; } } return false; } int main() { nNodesCount = 2; int M,N,i,w; scanf("%d%d%d",&N,&w,&M); //N个模式串,M个句子 for( i = 0;i < N; i ++ ) { char s[30]; scanf("%s",s); // printf("^^^^\n");////////// Insert(Tree + 1,s); } BuildDfa(); for( i = 0 ;i < M;i ++ ) { char s[200]; scanf("%s",s); cout << SearchDfa(s) << endl; } return 0; }