HDU2896 病毒的侵扰

http://vjudge.net/problem/viewProblem.action?id=16404

题目大意:

记录每个病毒的编号,并给出一些网站的源码,分别输出网站及其对应编号中所含病毒的编号,没有就不输出

最后输出有病毒网站的个数

 

这道题需要注意的是这个所有ASCII码均会用到,所以我之前傻傻地写str[i]-'a'还不知为什么会错简直苦逼~~

这里直接用ch[now][str[i]]找到对应位置即可

因为要记录编号,为了防止重复访问,我对query中进行了一个visit[]数组访问进行判断的操作

query函数如下:

 1  void query(char *str){
 2         int len=strlen(str);
 3         int now=root,ret=0;
 4         for(int i=0;i<len;i++){
 5             now=ch[now][str[i]];
 6             int k=now;
 7             while(k!=root&&(!visit[k]&&val[k])){//这是要循环到找到fail值为root的时候或者找到匹配的字符串的时候,否则一直向前找fail值,
 8                 if(!visit[k])sum++,ans[ret++]=val[k],visit[k]=1;
 9                 k=last[k];
10             }
11         }
12     }

用ans[]记录所有编号,sum记录病毒个数,那么就可以在main函数进行sort(ans,ans+sum)进行排序好就可以输出了

总代码如下:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #include <algorithm>
 5 using namespace std;
 6 #define N 500*201
 7 char str[10005];
 8 int ans[505],visit[N],sum;
 9 struct AC{
10     int ch[N][128],fail[N],val[N],last[N],tmp,root,cnt;
11     int newnode(){
12         val[tmp]=0;
13         memset(ch[tmp],0,sizeof(ch[tmp]));
14         return tmp++;
15     }
16     void init(){
17         tmp=0,cnt=0;
18         root=newnode();
19     }
20     void add(char *s){
21         int len=strlen(s);
22         int now=root;
23         for(int i=0;i<len;i++){
24             int &k=ch[now][s[i]];
25             if(!k) k=newnode();
26             now=k;
27         }
28         cnt++;
29         val[now]=cnt;
30     }
31     void get_fail(){
32         fail[root]=root;
33         queue<int> q;
34         for(int i=0;i<128;i++){
35             int v=ch[root][i];
36             if(v)
37                 fail[v]=last[v]=0,q.push(v);
38         }
39         while(!q.empty()){
40             int now=q.front();
41             q.pop();
42             for(int i=0;i<128;i++){
43                 int v=ch[now][i];
44                 if(!v) ch[now][i]=ch[fail[now]][i];
45                 else{
46                     fail[v]=ch[fail[now]][i];
47                     last[v]=val[fail[v]]?fail[v]:last[fail[v]];
48                     q.push(v);
49                 }
50             }
51         }
52     }
53     void query(char *str){
54         int len=strlen(str);
55         int now=root,ret=0;
56         for(int i=0;i<len;i++){
57             now=ch[now][str[i]];
58             int k=now;
59             while(k!=root&&(!visit[k]&&val[k])){//这是要循环到找到fail值为root的时候或者找到匹配的字符串的时候,否则一直向前找fail值,
60                 if(!visit[k])sum++,ans[ret++]=val[k],visit[k]=1;
61                 k=last[k];
62             }
63         }
64     }
65 }ac;
66 int main()
67 {
68     int n,m;
69     while(scanf("%d",&n)!=EOF){
70         memset(ans,0,sizeof(ans));
71         ac.init();
72         for(int i=0;i<n;i++){
73             scanf("%s",str);
74             ac.add(str);
75         }
76         ac.get_fail();
77         scanf("%d",&m);
78         int c=0;
79         for(int i=1;i<=m;i++){
80             sum=0;
81             scanf("%s",str);
82             memset(visit,0,sizeof(visit));
83             ac.query(str);
84             sort(ans,ans+sum);
85             if(sum>0){
86                 printf("web %d:",i);
87                 for(int j=0;j<sum;j++) printf(" %d",ans[j]);
88                 printf("\n");
89                 c++;
90             }
91         }
92         printf("total: %d\n",c);
93     }
94     return 0;
95 }
View Code

相关文章:

  • 2021-12-14
  • 2022-02-22
  • 2021-11-13
  • 2022-01-05
  • 2021-12-06
  • 2021-11-17
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-05-24
  • 2021-07-10
  • 2022-01-31
  • 2021-06-06
  • 2022-12-23
  • 2021-06-15
  • 2021-07-10
相关资源
相似解决方案