【练习05】 AC自动机 1001 病毒侵袭
2013-07-22 13:01
651 查看
算法思路:AC自动机。
要点:
1.val存储病毒的编号;
2.find函数中当找到一个模板后,应该顺着失配边往回走,由last数组递归判断是否还有其他的子模板能够匹配,所有找到的模板的val值保存到数组save中。
3.对save数组进行sort排序,注意输出格式,依次打印病毒编号。
4.题中要求是“可见字符”,在不超内存的情况下,sigma_size最好开到127。
要点:
1.val存储病毒的编号;
2.find函数中当找到一个模板后,应该顺着失配边往回走,由last数组递归判断是否还有其他的子模板能够匹配,所有找到的模板的val值保存到数组save中。
3.对save数组进行sort排序,注意输出格式,依次打印病毒编号。
4.题中要求是“可见字符”,在不超内存的情况下,sigma_size最好开到127。
//模板开始 #include <string> #include <vector> #include <algorithm> #include <iostream> #include <sstream> #include <fstream> #include <map> #include <set> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <iomanip> #include <string.h> #include <queue> #define SZ(x) (int(x.size())) using namespace std; int toInt(string s){ istringstream sin(s); int t; sin>>t; return t; } template<class T> string toString(T x){ ostringstream sout; sout<<x; return sout.str(); } typedef long long int64; int64 toInt64(string s){ istringstream sin(s); int64 t; sin>>t; return t; } template<class T> T gcd(T a, T b){ if(a<0) return gcd(-a, b); if(b<0) return gcd(a, -b); return (b == 0)? a : gcd(b, a % b); } //模板结束(通用部分) #define ifs cin #define maxnode 100005 #define sigma_size 127 int save[maxnode]; int cnt; struct Trie { int ch[maxnode][sigma_size]; int val[maxnode]; int sz; int f[maxnode]; int last[maxnode]; Trie() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } int idx(char c) { return (int)c; } void insert(char* s, int v) { int u = 0, n = strlen(s); for(int i = 0; i < n; i++) { int c = idx(s[i]); if(!ch[u][c]) { memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = v; } //int search(char* s, int n) //{ // int u = 0; // int flag = 1; // for(int i = 0; i < n; i++) // { // int c = idx(s[i]); // if(ch[u][c] == 0) // { // flag = 0; // break; // } // u = ch[u][c]; // } // if(flag && val[u]) // { // return 1; // } // else // { // return 0; // } //} void getFail() { queue<int> q; f[0] = 0; for(int c = 0; c < sigma_size; c++) { int u = ch[0][c]; if(u) { f[u] = 0; q.push(u); last[u] = 0; } while(!q.empty()) { int r = q.front(); q.pop(); for(int c = 0; c < sigma_size; c++) { int u = ch[r][c]; if(!u) { continue; } q.push(u); int v = f[r]; while(v && !ch[v][c]) { v = f[v]; } f[u] = ch[v][c]; last[u] = val[f[u]] ? f[u] : last[f[u]]; } } } } void save_all(int j) { if(j) { save_all(last[j]); save[cnt++] = val[j]; } } void find(char* T) { int n = strlen(T); int j = 0; for(int i = 0; i < n; i++) { int c = idx(T[i]); while(j && !ch[j][c]) { j = f[j]; } j = ch[j][c]; if(val[j]) { save_all(j); } else { if(last[j]) { save_all(last[j]); } } } } }; Trie t; char a[505][205]; char b[10005]; int jishu; //【练习05】 AC自动机 1001 病毒侵袭 int main() { //ifstream ifs("shuju.txt", ios::in); int n; while(ifs>>n) { for(int i = 1; i <= n; i++) { //ifs>>a[i]; scanf("%s", &a[i]); t.insert(a[i], i); } t.getFail(); ifs>>n; jishu = 0; for(int i = 1; i <= n; i++) { //ifs>>b; scanf("%s", &b); cnt = 0; memset(save, 0, sizeof(save)); t.find(b); if(!save[0]) { continue; } else { jishu++; } sort(save, save + cnt); cout<<"web "<<i<<":"; for(int j = 0; j < cnt; j++) { cout<<" "<<save[j]; } cout<<endl; } cout<<"total: "<<jishu<<endl; } return 0; }
相关文章推荐
- [hdu2896] 病毒侵袭 AC自动机
- SDAU课程练习--problemB(1001)
- AC自动机---病毒侵袭
- 【多题合集】AC自动机练习,被HDU支配的恐惧
- 课程练习二-1001
- 【模板练习——AC自动机】Keywords Search HDU - 2222
- 病毒侵袭(ac自动机模板)
- AC自动机 病毒侵袭持续中 HDU - 3065
- Hdu 2896 病毒侵袭 AC自动机
- HDU2896 病毒侵袭[AC自动机]
- HDU3065[病毒侵袭持续中] AC自动机
- HDOJ 2896 病毒侵袭(AC自动机入门)
- 【练习02】 简单题(2)1001 Higher Math
- 【05】SSH练习——struts2和json 的整合
- 课程练习一 Problem B id 1001
- HDU 3065 病毒侵袭持续中【AC自动机】
- 【练习04】 字典树 1001 Hat’s Words
- 【HDU】3065 病毒侵袭持续中 AC自动机
- 【AC自动机】 HDOJ 2896 病毒侵袭
- [HDU 2896]病毒侵袭[AC自动机]