hdu 2896:病毒侵袭

news/2024/7/7 18:38:59

        Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
            Total Submission(s): 18206    Accepted Submission(s): 4541

Problem Description
  当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻。。。。在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~
  但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
  万事开头难,小t收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
Input
  第一行,一个整数N(1<=N<=500),表示病毒特征码的个数。
  接下来N行,每行表示一个病毒特征码,特征码字符串长度在20—200之间。
  每个病毒都有一个编号,依此为1—N。
  不同编号的病毒特征码不会相同。
  在这之后一行,有一个整数M(1<=M<=1000),表示网站数。
  接下来M行,每行表示一个网站源码,源码字符串长度在7000—10000之间。
  每个网站都有一个编号,依此为1—M。
  以上字符串中字符都是ASCII码可见字符(不包括回车)。
Output
  依次按如下格式输出按网站编号从小到大输出,带病毒的网站编号和包含病毒编号,每行一个含毒网站信息。
  web 网站编号: 病毒编号 病毒编号 …
  冒号后有一个空格,病毒编号按从小到大排列,两个病毒编号之间用一个空格隔开,如果一个网站包含病毒,病毒数不会超过3个。
  最后一行输出统计信息,如下格式
  total: 带病毒网站数
  冒号后有一个空格。
Sample Input
  3 aaa bbb ccc 2 aaabbbccc bbaacc
Sample Output
  web 1: 1 2 3 total: 1
题解:
  AC自动机,注意病毒特征码和网站源码不只有小写字母,还有输出的时候要注意格式,具体看代码。
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<queue>
  5 #include<algorithm>
  6 #include<cmath>
  7 using namespace std;
  8 typedef long long LL;
  9 const int maxn=100010;
 10 char buf[maxn];
 11 int N,M,cnttot;
 12 int ans[maxn],cntweb;
 13 struct Tire{
 14     int next[maxn][130],end[maxn];
 15     vector<int> kin[maxn];
 16     int fail[maxn],root,tot;
 17     int newnode(){
 18         for(int i=0;i<128;i++) next[tot][i]=-1;
 19         end[tot++]=0;
 20         return tot-1;
 21     }
 22     void init(){
 23         tot=0;
 24         root=newnode();
 25     }
 26     void insert(char buf[],int k){//把第 k种类型的病毒信息放在字典树中 
 27         int len=strlen(buf);
 28         int now=root;
 29         for(int i=0;i<len;i++){
 30             if(next[now][buf[i]]==-1) next[now][buf[i]]=newnode();
 31             now=next[now][buf[i]];
 32         }
 33         end[now]++; kin[now].push_back(k);
 34     }
 35     void build(){
 36         queue<int> Q;
 37         fail[root]=root;
 38         for(int i=0;i<128;i++){
 39             if(next[root][i]==-1) next[root][i]=root;
 40             else{
 41                 fail[next[root][i]]=root;
 42                 Q.push(next[root][i]);
 43             }
 44         }
 45         while(!Q.empty()){
 46             int now=Q.front(); Q.pop();
 47             for(int i=0;i<128;i++){
 48                 if(next[now][i]==-1) next[now][i]=next[fail[now]][i];
 49                 else{
 50                     fail[next[now][i]]=next[fail[now]][i];
 51                     Q.push(next[now][i]);
 52                 }
 53             }
 54         }
 55     }
 56     bool used[maxn];
 57     void query(char buf[],int num){
 58         int len=strlen(buf),now=root;
 59         memset(used,false,sizeof(used));
 60         for(int i=0;i<len;i++){
 61             now=next[now][buf[i]];
 62             int tmp=now;
 63             while(tmp!=root){
 64                 if(end[tmp]!=0){
 65                     for(int j=0;j<kin[tmp].size();j++){
 66                         int y=kin[tmp][j];
 67                         if(used[y]==false){
 68                             ans[++cntweb]=y;
 69                             used[y]=true;
 70                         }
 71                     }
 72                 }
 73                 tmp=fail[tmp];
 74             }
 75         }
 76         if(cntweb!=0){
 77             cnttot++;
 78             sort(ans+1,ans+cntweb+1);
 79             printf("web %d:",num);
 80             for(int i=1;i<=cntweb;i++) printf(" %d",ans[i]);
 81             printf("\n");
 82             memset(ans,0,sizeof(ans)); cntweb=0;
 83         }
 84     }
 85 }ac;
 86 int main(){
 87     scanf("%d",&N);
 88     ac.init();
 89     for(int i=1;i<=N;i++){
 90         scanf("%s",buf);
 91         ac.insert(buf,i);
 92     }
 93     ac.build();
 94     scanf("%d",&M);
 95     for(int i=1;i<=M;i++){
 96         scanf("%s",buf);
 97         ac.query(buf,i);
 98     }
 99     printf("total: %d\n",cnttot);
100     return 0;
101 }

转载于:https://www.cnblogs.com/CXCXCXC/p/5171285.html


http://lihuaxi.xjx100.cn/news/286073.html

相关文章

poj1548(最小路径覆盖问题)

题意&#xff1a;相当于给出N个坐标点&#xff0c;因为机器人只能向下或者向右走&#xff0c;所以如果能到达其他点&#xff0c;则连接这两个点&#xff0c;即line[i][j]1 最小路径覆盖数: 对于一个DAG&#xff08;有向无环图&#xff09;&#xff0c;选取最少条路径&#xff0…

Prime Path(bfs)广度优先搜索

题目描述 The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices. — It is a matter of security to change such things every now and the…

一些改进模型速度/精度的工程方法

点击上方“视学算法”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达作者&#xff1a;Captain Jackhttps://zhuanlan.zhihu.com/p/92025012本文已由作者授权&#xff0c;未经允许&#xff0c;不得二次转载一些自己的工作经验总结&#xff0c;用…

HDU4160(最小路径覆盖问题)

题意&#xff1a;当满足条件wi<wj,hi<hl和li<lj时&#xff0c;求解通过优化嵌套给定的娃娃可以获得的最外层洋娃娃的最小数量。 思路&#xff1a;如果嵌套的娃娃越多&#xff0c;则剩下的娃娃就越少&#xff0c;意味着单独出来的娃娃越少&#xff0c;转换为求解最小路…

线段树分治 ---- CF1217F - Forced Online Queries Problem(假离线 可撤销并查集 + 线段树分治)详解

题目链接 题目大意 解题思路&#xff1a; 我一开始想到可以用可撤销并查集去维护这种删边加边的操作&#xff0c;但是有个缺点是每次撤销都有把后面的边全部撤销复度是O(n2)O(n^2)O(n2) 首先我们考虑这种动态加边删边的问题&#xff0c;如果是离线的话&#xff0c;那就是线段…

秘籍 | 机器学习数据集网址大全

作者 | Will Badr译者 | Linstancy整理 | Jane出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;要找到一定特定的数据集可以解决各种机器学习问题&#xff0c;是一件很难的事情。越来越多企业或研究机构将自己的数据集公开&#xff0c;已经成为全球的趋势&#xff0c;…

第一个Servlet和Jsp

为什么80%的码农都做不了架构师&#xff1f;>>> 第一个Servlet和Jsp 开发Servlet有3种方法1.Servlet接口2.继承GenericServlet3.继承HttpServlet Tomcat 9部署Servlet 1.Tomcat的安装目录的webapps目录&#xff0c;可以看到ROOT&#xff0c;examples, tomcat-docs之…

Dungeon Master(bfs)广度优先搜索

描述 You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonal…