AC自动机(hdu 2896 hdu 3065)
来源:互联网 发布:阿里java工资水平 编辑:程序博客网 时间:2024/05/16 19:55
题目:hdu 2896
题意:中文题目,可自己理解,简单说就是给定一些子字符串,再给出一些母字符串,找出母字符串中包含哪些子字符串
题解:AC自动机模板题
代码:
动态申请:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<queue>#define MAX 59999using namespace std;struct Node{ int number; Node *next[128]; Node *fail; Node() { number=0; fail=NULL; for(int i=0;i<128;i++) next[i]=NULL; }};queue<Node*> q;Node *root;bool vis[600];int no;char son[256];char father[100500];void insertTree(char *s){ int len=strlen(s); int index; Node *temp=root; for(int i=0;i<len;i++) { index=s[i]-' '; if(temp->next[index]==NULL) { temp->next[index]=new Node(); } temp=temp->next[index]; } temp->number=no++;}void buildacfail(){ q.push(root); Node *temp; Node *p; while(!q.empty()) { temp=q.front(); q.pop(); for(int i=0;i<128;i++) { if(temp->next[i]!=NULL) { if(temp==root) { temp->next[i]->fail=root; } else { 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.push(temp->next[i]); } } }}int query(char *s){ int len=strlen(s); Node *temp=root; Node *p; int index; int sum=0; for(int i=0;i<len;i++) { index=s[i]-' '; while(temp->next[index]==NULL && temp!=root) { temp=temp->fail; } temp=temp->next[index]; if(temp==NULL) { temp=root; } p=temp; while(temp!=root && !vis[temp->number]) { if(temp->number) { sum++;vis[temp->number]=1; } temp=temp->fail; } temp=p; } return sum;}int main(){ int n,m,sum; while(~scanf("%d", &n)) { root =new Node(); no=1; getchar(); for(int i = 0; i < n; ++i) { gets(son); insertTree(son); } buildacfail(); scanf("%d",&m); getchar(); memset(vis,0,sizeof(vis)); sum=0; for(int i=0;i<m;i++) { scanf("%s", father); int count1=query(father); if(count1) { sum++; printf("web %d:",i+1); for(int j=1;j<=n;j++) { if(vis[j]){printf(" %d",j);vis[j]=0;count1--;} if(!count1) break; } printf("\n"); } } printf("total: %d\n",sum); } return 0;}
静态存储:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<queue>using namespace std;struct Node{ int number; Node *next[128]; Node *fail;};queue<Node*> q;Node *root;Node node[1000050];int num;int no;bool vis[505];char son[300];char father[10050];void declear(Node *p){ p->number=0; p->fail=NULL; for(int i=0;i<128;i++) { p->next[i]=NULL; }}void insertTree(char *s){ int len=strlen(s); int index; Node *temp=root; for(int i=0;i<len;i++) { index=s[i]-' '; if(temp->next[index]==NULL) { temp->next[index]=&node[num]; declear(node+num); num++; } temp=temp->next[index]; } temp->number=no++;}void buildacfail(){ q.push(root); Node *temp; Node *p; while(!q.empty()) { temp=q.front(); q.pop(); for(int i=0;i<128;i++) { if(temp->next[i]!=NULL) { if(temp==root) { temp->next[i]->fail=root; } else { 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.push(temp->next[i]); } } }}int query(char *s){ int len=strlen(s); Node *temp=root; Node *p; int index; int sum=0; for(int i=0;i<len;i++) { index=s[i]-' '; while(temp->next[index]==NULL && temp!=root) { temp=temp->fail; } temp=temp->next[index]; if(temp==NULL) { temp=root; } p=temp; while(temp!=root && !vis[temp->number]) //考虑重复情况,不用记录次数,只要记录之前有没出现过即可,后面的就不用考虑了 { if(temp->number!=0) { sum++; vis[temp->number]=1; } temp=temp->fail; } temp=p; } return sum;}int main(){ int n,m,sum; while(~scanf("%d", &n)) { root = node; num=1; no=1; declear(node); getchar(); for(int i = 0; i < n; ++i) { gets(son); insertTree(son); } buildacfail(); scanf("%d",&m); getchar(); memset(vis,0,sizeof(vis)); sum=0; for(int i=0;i<m;i++) { scanf("%s", father); int count1=query(father); if(count1) { sum++; printf("web %d:",i+1); for(int j=1;j<=n;j++) { if(vis[j]){printf(" %d",j);vis[j]=0;count1--;} if(!count1) break; } printf("\n"); } } printf("total: %d\n",sum); } return 0;}
题目:hdu 3065
题意:中文题目,简单说就是给定一些大写字母组成的子串,再给出母串,求其母串中子串各出现了多少次
题解:AC模板题,主要解释看注释
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<queue>using namespace std;struct Node{ int number; Node *next[26]; Node *fail;};queue<Node*> q;Node *root;Node node[5000050];int num;int no;int vis[1505];char son[1005][60];char father[2000500];void declear(Node *p){ p->number=0; p->fail=NULL; for(int i=0;i<26;i++) { p->next[i]=NULL; }}void insertTree(char *s){ int len=strlen(s); int index; Node *temp=root; for(int i=0;i<len;i++) { index=s[i]-'A'; if(temp->next[index]==NULL) //增加节点 { temp->next[index]=&node[num]; declear(node+num); num++; } temp=temp->next[index]; } temp->number=no++;}void buildacfail(){ q.push(root); Node *temp; Node *p; while(!q.empty()) { temp=q.front(); q.pop(); for(int i=0;i<26;i++) { if(temp->next[i]!=NULL) { if(temp==root) { temp->next[i]->fail=root; } else { 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.push(temp->next[i]); } } }}void query(char *s){ int len=strlen(s); Node *temp=root; Node *p; int index; for(int i=0;i<len;i++) { index=s[i]-'A'; if(index>=26 ||index<0 ) {temp=root;continue;} while(temp->next[index]==NULL && temp!=root) { temp=temp->fail; } temp=temp->next[index]; if(temp==NULL) { temp=root; } p=temp; while(temp!=root) //全部进行遍历,而不是,这道题改的就是这里,不是重新开始,而是顺着现在的遍历,一定不会重复 { if(temp->number!=0) { vis[temp->number]++; } temp=temp->fail; } temp=p; }}int main(){ int n,m,sum; while(~scanf("%d", &n)) { memset(vis,0,sizeof(vis)); root = node; num=1; no=1; declear(node); getchar(); for(int i = 0; i < n; ++i) { gets(son[i]); insertTree(son[i]); } buildacfail(); scanf("%s", father); query(father); for(int i=1;i<=n;i++) { if(vis[i]) printf("%s: %d\n",son[i-1],vis[i]); } } return 0;}
0 0
- AC自动机(hdu 2896 hdu 3065)
- AC自动机小结 (HDU 2222,HDU 2896,HDU 3065)
- hdu 3065(ac自动机)
- HDU 3065 (AC自动机)
- hdu 2896 (AC自动机)
- hdu 3065(AC自动机)
- HDU 3065 AC自动机
- hdu 3065 AC自动机
- HDU 3065(ac自动机)
- HDU 3065 AC自动机
- HDU 3065 AC自动机
- hdu 3065 AC自动机
- hdu 3065 AC自动机
- HDU 3065 (AC自动机)
- HDU 3065 AC自动机
- hdu 3065-AC自动机
- hdu 3065 ac自动机
- HDU 2896 AC自动机
- Linux安装包格式和安装方法研究
- mysql slave不能同步Last_SQL_Error: Error ‘Duplicate entry ‘
- 了解Android中的Preference结构的设计与实现
- Python实用工具介绍
- 页面的下拉加载效果基于ajax加载数据
- AC自动机(hdu 2896 hdu 3065)
- ubuntu14.04下载blender
- 中国科学院朱清时:量子意识(人人能懂版)
- 业务知识(2)立案与受理的区别&&裁定书和判决书的区别
- 如何正确使用html基本标签
- 蓝鸥Unity开发基础——静态类
- SpringMVC中用@ParamVariable传递的参数包含斜杠(/)时,匹配不了报404错误的解决方案
- ColorDrawable.setAlph在5.0一下机子失效
- android 中的颜色设置