初学ac自动机,拿别人的代码作别模板修改的。 之前用query()查询的时候,查询到一个合适解就返回了,wa了n次,自己竟然犯这么低级错误,太不应该了 这次看了别人的代码后受益良多,以此记载一下 #include<iostream> #include <stdio.h> #include <string.h> using namespace std; #define TXTL 1005 //子树节点是在插入时new的, //寻找失配指针中使用的队列是用数组模拟的 const int kind = 26;//子树个数 struct node { node *fail; node *next[kind]; int count;//记录当前前缀是完整单词出现的个数 node() { fail = NULL; count = -1; memset(next,0,sizeof(next)); } }*q[1000001];//寻找失配指针时需要用到的队列 struct CWord{ char data[1001]; int wordlen; int row,col; char ori; }; const int dir[][2] = { {-1, 0},{-1, 1},{0, 1},{1, 1},{1, 0},{1, -1},{0, -1},{-1, -1} }; char wp[TXTL][TXTL]; CWord words[TXTL]; int row, col, n; void insert(node *root, char *str, int id) { node *p=root; int i=0,index; while(str[i]) { index = str[i]-'A'; if(p->next[index]==NULL) p->next[index]=new node(); p=p->next[index]; i++; } p->count = id; } //寻找失败指针 void build_ac_automation(node *root) { int i; int head,tail; root->fail = NULL; head = 0; tail = 0; q[tail++] = root; while(head!=tail) { node *temp = q[head++];//取队首元素 node *p = NULL; for(i=0;i<kind;i++) { if(temp->next[i]!=NULL)//寻找当前子树的失败指针 { p = temp->fail; while(p!=NULL) { if(p->next[i]!=NULL)//找到失败指针 { temp->next[i]->fail = p->next[i]; break; } p = p->fail; } if(p==NULL)//无法获取,当前子树的失败指针为根 temp->next[i]->fail = root; q[tail++]=temp->next[i];//当前子树入队 } } } } //询问str中包含n个关键字中多少种 void query(node *root, char *str, int &wordid, int ir, int ic, int di) { int i = 0,cnt = 0,index,len; len = strlen(str); node *p = root; while(str[i]) { index = str[i]-'A'; while(p->next[index]==NULL&&p!=root)//失配 p=p->fail; p=p->next[index]; if(p==NULL)//失配指针为根 p = root; node *temp = p; while(temp!=root)//标记本次过程中访问过的点 { if(temp->count!=-1) { wordid = temp->count; //return i; 这里之前查询到一个合适解就返回了,wa了n次,自己竟然犯这么低级错误,太不应该了 words[wordid].row = ir + (i - words[wordid].wordlen + 1)*dir[di][0]; words[wordid].col = ic + (i - words[wordid].wordlen + 1)*dir[di][1]; words[wordid].ori = di + 'A'; } temp=temp->fail; } i++; } } inline int inBound(int r, int c) { return 0 <= r && r < row && 0 <= c && c < col; } void findsub(node *root, int ir, int ic, int di) { int js,wordid,rs; char ss[TXTL]; for(js = 0; inBound(ir + js*dir[di][0], ic + js*dir[di][1]); ++js) { ss[js] = wp[ir + js*dir[di][0]][ic + js*dir[di][1]]; } ss[js] = '/0'; query(root, ss, wordid, ir, ic, di); } int main() { scanf("%d%d%d", &row, &col, &n); node *root = new node(); for(int i = 0; i < row; ++i) { scanf("%s", wp[i]); } for(int i = 0; i < n; ++i) { scanf("%s", words[i].data); words[i].wordlen = strlen(words[i].data); insert(root, words[i].data, i); } //求失败指针 build_ac_automation(root); for(int i = 0; i < n; ++i) { words[i].col = words[i].row = words[i].ori = -100; } for(int j = col-1; j >= 0; --j) { findsub(root, 0, j, 3); findsub(root, 0, j, 4); findsub(root, 0, j, 5); findsub(root, row-1, j, 7); findsub(root, row-1, j, 0); findsub(root, row-1, j, 1); } for(int i = row-1; i >= 0; --i) { findsub(root, i, 0, 1); findsub(root, i, 0, 2); findsub(root, i, 0, 3); findsub(root, i, col-1, 5); findsub(root, i, col-1, 6); findsub(root, i, col-1, 7); } for(int i = 0; i < n; ++i) { printf("%d %d %c/n", words[i].row, words[i].col, words[i].ori); } return 0; }