http://acm.hdu.edu.cn/showproblem.php?pid=2896
对于hdu oj...发现如果数组越界,还有数组下标为负数 ,可能返回的Judge结果都是WA而不是RE。。。这道题WA了几次,因为
inline int idx(char c) { //return c-'a'; //这里一定小心,如果没有给定字符范围的话,直接return c; //因为可能出现负的...病毒侵袭那题就是 return c; }
2、AC自动机注意首先看字符范围,定下SIGMA_SIZE以及idx函数写法
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int SIZE = 10000+10; const int SIGMA_SIZE = 128; const int MAXNODE = 61000; //const int MAXS = 150 + 10; int maxv; struct AC { int f[MAXNODE]; int ch[MAXNODE][SIGMA_SIZE]; int val[MAXNODE]; int last [MAXNODE]; int cnt[MAXNODE]; int sz; void init() { sz=1; memset(ch[0],0,sizeof(ch[0])); memset(cnt,0,sizeof(cnt)); val[0]=f[0]=last[0]=0; } void clear() { memset(cnt,0,sizeof(cnt)); } inline int idx(char c) { //return c-'a'; //这里一定小心,如果没有给定字符范围的话,直接return c; //因为可能出现负的...病毒侵袭那题就是 return 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; } 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 print(int j) { if(j) { maxv=max(val[j],maxv); cnt[val[j]]++; print(last[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]) print(j); else if(last[j])print(last[j]); } } }; AC ac; int main() { //freopen("hdu2896.txt","r",stdin); int n,m; char str[SIZE]; while(scanf("%d",&n) !=EOF) { ac.init(); for(int i=1;i<=n;i++) { scanf("%s",str); ac.insert(str,i); } ac.getfail(); scanf("%d",&m); int wcnt=0,flag=0; for(int i=1;i<=m;i++) { maxv=0; flag=0; ac.clear(); scanf("%s",str); ac.find(str); for(int j=1;j<=maxv;j++) { if(ac.cnt[j]) { flag++; if(flag==1)printf("web %d: ",i); if(j<maxv)printf("%d ",j); else printf("%d\n",j); } } if(flag)wcnt++; } printf("total: %d\n",wcnt); } return 0; }
hdu 2896 病毒侵袭 AC自动机,布布扣,bubuko.com
原文地址:http://blog.csdn.net/u011026968/article/details/38051293