本文共 3076 字,大约阅读时间需要 10 分钟。
链接:
题目:
3aaabbbccc2aaabbbcccbbaacc
web 1: 1 2 3total: 1
分析与总结:
AC自动机的模板题,这题需要注意的是字符范围是“可见字符”, ASCII码范围是33~126。因为这个原因RE了很多次。
另外,我的代码竟然很神奇地跑到了rank1
代码:
#include#include #include #include using namespace std;const int MAX_NODE = 1000005;const int SIGMA_SIZE = 126-32;char str[10005];bool hash[600];struct node{ node* fail; node* next[SIGMA_SIZE]; int id; int count; void init(){ id=0; count=0; memset(next, 0, sizeof(next)); }};class AC_Automation{public: void init(); void insert(char* str, int id); void getFail(); bool find(char* str);private: node* new_node(); node Heap[MAX_NODE]; node* root; int size;};node* AC_Automation::new_node(){ Heap[size].init(); return &Heap[size++];}void AC_Automation::init(){ size=0; root = new_node();}void AC_Automation::insert(char* str,int id){ node* p=root; for( ; *str; ++str){ int ch=*str-33; if(p->next[ch] == NULL) p->next[ch] = new_node(); p = p->next[ch]; } p->id=id; ++p->count;}void AC_Automation::getFail(){ queue Q; Q.push(root); while(!Q.empty()){ node* tmp=Q.front(); Q.pop(); for(int i=0; i next[i]; if(now != NULL){ Q.push(now); if(tmp==root) now->fail=root; else{ node* p=tmp->fail; while(p != NULL){ if(p->next[i] != NULL){ now->fail = p->next[i]; break; } p = p->fail; } if(p==NULL) now->fail=root; } } else{ if(tmp==root) now=root; else now=tmp->fail->next[i]; } } }}bool AC_Automation::find(char* str){ node* p=root; bool ok=false; memset(hash, 0, sizeof(hash)); for( ; *str; ++str){ int ch=*str-33; p = p->next[ch]; if(p==NULL) p=root; node* tmp=p; while(tmp!=root && tmp->count){ if(tmp->count){ ok=true; hash[tmp->id] = true; } tmp = tmp->fail; } } return ok;}AC_Automation ac;int main(){ int n,m; char code[205]; scanf("%d%*c",&n); ac.init(); for(int i=1; i<=n; ++i){ gets(code); ac.insert(code,i); } ac.getFail(); scanf("%d%*c",&m); int cnt=0; for(int i=1; i<=m; ++i){ gets(str); if(ac.find(str)){ ++cnt; printf("web %d:", i); for(int j=1; j<=n; ++j)if(hash[j]){ printf(" %d",j); } puts(""); } } printf("total: %d\n",cnt); return 0;}
—— 生命的意义,在于赋予它意义士。
原创 , By D_Double (转载请标明)