HDU 2896 AC自动机
来源:互联网 发布:浙江大学软件学院邮编 编辑:程序博客网 时间:2024/06/05 00:28
中文题,题意就不解释了。
这道题把我坑了下,应该是做题不仔细的原因,一开始我以为是26个字母的(没认真读题,看样例的结果) ,然后RE了好几发,最多发现题目里的描述是ASCLL码表里面的可见字符,然后将建字典树过程中的0 - 25的循环改成0 - 127 就过了。
讲一下思路,这道题就是AC自动机的模版题,唯一需要注意的就是加一个id的域来存这个字符串的序号,最后输出的时候要按从小到大的顺序,我直接全部扔进set输出了。
不过我感觉数据有点水啊。。。总感觉A的不是很踏实。
加了释放内存,但是发现内存没比原来的少,难道数据只有一组o(︶︿︶)o
#include <iostream>#include <cstdio>#include <algorithm>#include <string>#include <cmath>#include <cstring>#include <queue>#include <set>#include <vector>#include <stack>#include <map>#include <iomanip>#define PI acos(-1.0)#define Max 2505#define inf 1<<28#define LL(x) ( x << 1 )#define RR(x) ( x << 1 | 1 )#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define mp(a,b) make_pair(a,b)#define PII pair<int,int>using namespace std;struct node { node *fail ; node *next[128] ; int count ; int id ; node() { fail = 0 ; count = 0 ; mem(next , 0) ; id = 0 ; }}*qe[1000005] ;node *root = 0 ;//insert a[] .void insert(char *a,int id) { node *p = root ; int l = strlen(a) ; for (int i = 0 ; i < l ; i ++ ) { int tt = a[i] ; if(p -> next[tt] == 0) { p -> next[tt] = new node() ; } p = p -> next[tt] ; } p -> count ++ ; p -> id = id ;}//build *fail .void build() { root -> fail = 0 ; int h = 0 , t = 0 ; qe[h ++ ] = root ; while(h > t) { node *temp = qe[t ++ ] ; node *p = 0 ; for (int i = 0 ; i < 128 ; i ++ ) { if(temp -> next[i] != 0) { if(temp == root)temp -> next[i] -> fail = root ; else { p = temp -> fail ; while(p != 0) { if(p -> next[i] != 0) { temp -> next[i] -> fail = p -> next[i] ;//找到匹配 break ; } p = p -> fail ; } if(p == 0)temp -> next[i] -> fail = root ;//如果没找到,则将fail指向root } qe[h ++ ] = temp -> next[i] ; } } }}set<int>anss[1111] ;int search(char *a ,int id) { int l = strlen(a) ; node *p = root ; int ans = 0 ; for (int i = 0 ; i < l ; i ++ ) { int tt = a[i] ; while(p -> next[tt] == 0 && p != root)p = p -> fail ; p = p -> next[tt] ; p = (p == 0) ? root : p ; node *temp = p ; while(temp != root && temp -> count != 0) { ans += temp -> count ; anss[id].insert(temp -> id) ; //temp -> count = -1 ; temp = temp -> fail ; } } return ans ;}void deleteAll(node *p){ for (int i = 0 ; i < 128 ; i ++ ) if(p -> next[i] != 0){ deleteAll(p -> next[i]) ; } delete p ;}char a[11111] ;int num[1111] ;int main() { int n ; cin >> n ; getchar() ; root = new node() ; for (int i = 1 ; i <= n ;i ++ ){ gets(a) ; insert(a ,i ) ; } int m ; cin >> m ; getchar() ; build() ; for (int i = 1 ; i <= m ;i ++ ){ gets(a) ; num[i] = search(a , i) ; } int cc = 0 ; for (int i = 1 ; i <= m ;i ++ ){ if(num[i]){ printf("web %d:",i) ; for(set<int>::iterator p = anss[i].begin() ; p != anss[i].end() ; ++ p) cout <<" "<< *p ; cc ++ ; puts("") ; } } printf("total: %d\n",cc) ; deleteAll(root) ; return 0 ;}
贴一个AC自动机静态的模版
#include<iostream>#include<cstring>#include<cstdio>#include<queue>#include <set>using namespace std;char ss[1000010];int n,cnt,ans;struct node { int num; int next[128]; int fail; int id ; void init() { memset(next,-1,sizeof(next)); fail=-1; num=0; id = 0 ; }} a[500000];void insert(char s[],int id) { int p=0,i=0; int len=strlen(s); while(i<len) { int k=s[i] ; if(a[p].next[k]==-1) { a[cnt].init(); a[p].next[k]=cnt++; } i++; p=a[p].next[k]; } a[p].num++; a[p].id = id ;}queue<int>q;void ac_bfs() { q.push(0); while(!q.empty()) { int p=q.front(); q.pop(); int fail=0; for(int i=0; i<128; i++)if(a[p].next[i]!=-1) { if(p==0) { a[a[p].next[i]].fail=p; } else { fail=a[p].fail; while(fail!=-1) { if(a[fail].next[i]!=-1) { a[a[p].next[i]].fail=a[fail].next[i]; break; } fail=a[fail].fail; } if(fail==-1)a[a[p].next[i]].fail=0; } q.push(a[p].next[i]); } }}set<int>fk[1111] ;int query(char s[] ,int id) { int i=0,len=strlen(s); int p=0,ans=0; while(i<len) { int k=s[i] ; while(a[p].next[k]==-1&&p!=0)p=a[p].fail; p=a[p].next[k]; p=(p==-1)?0:p; int tmp=p; while(tmp!=0 && a[tmp].num != 0) { ans+=a[tmp].num; fk[id].insert(a[tmp].id) ; tmp=a[tmp].fail; } i++; } return ans;}char virus[11111] ;int fkk[1111] ;int main() { int n ; cin >> n ; cnt = 1 ; a[0].init() ; getchar() ; for (int i = 1 ; i <= n ; i ++ ) { gets(virus) ; insert(virus,i) ; } int m ; cin >> m ; ac_bfs() ; getchar() ; int cc = 0 ; for (int i = 1 ; i <= m ; i ++ ) { gets(virus) ; fkk[i] = query(virus , i) ; } for (int i = 1 ; i <= m ; i ++ ) { if(fkk[i]) { printf("web %d:",i) ; for(set<int>::iterator p = fk[i].begin() ; p != fk[i].end() ; ++ p) cout <<" "<< *p ; cc ++ ; puts("") ; } } printf("total: %d\n",cc) ; return 0 ;}
- HDU 2896 AC自动机
- HDU 2896 AC自动机
- hdu 2896 ac自动机
- HDU 2896 AC自动机
- HDU 2896 AC自动机
- HDU 2896 AC自动机
- hdu 2896 AC自动机
- hdu 2896 ac自动机
- hdu 2896(ac自动机)
- HDU 2896 AC自动机
- AC 自动机 HDU 2896
- HDU 2896 (AC自动机)
- hdu 2896AC自动机
- HDU 2896 AC自动机
- hdu 2896 ac自动机
- HDU-2896-AC自动机
- AC自动机 模板 hdu 2896
- HDU 2896 AC自动机 裸题
- QWT绘图
- 面试题24:二叉搜索树与双向链表
- android基础篇------------java基础(7)(Calendar和Data和SimpleDateFormat)
- 黑马程序员__网络编程
- C++编程技术之 异常处理(上)
- HDU 2896 AC自动机
- adb 如果连接不上安卓设备
- 数组排序
- mssql下创建ORACLE链接服务器,以便mssql远程访问oracle中数据
- 笔记OCP
- USACO Section 1.3.2 Barn Repair
- Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建胜过Apache十倍的Web服务器
- zoj1117 - Entropy(贪心)
- Linux jvm 分析