【BZOJ2938】病毒,AC自动机练习
传送门(权限题)
2938: [Poi2000]病毒
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 462 Solved: 240
[Submit][Status][Discuss]
Description
二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。
示例:
例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。
任务:
请写一个程序:
l 读入病毒代码;
l 判断是否存在一个无限长的安全代码;
l 将结果输出
Input
第一行包括一个整数n,表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。
Output
你应在在文本文件WIN.OUT的第一行输出一个单词:
l TAK——假如存在这样的代码;
l NIE——如果不存在。
Sample Input
3
01
11
00000
Sample Output
NIE
写在前面:给了三个样例的良心题
思路:
我们首先确定,如果可能,那么符合条件的字符串中一定有一个循环的字符串,如果不可能,那一定没有循环的字符串(因为循环的字符串是有循环节的,如果没有循环的字符串,那就意味着所有的循环节都不可以,那就是没有符合条件的了,反之亦如此)
然后偷个懒
zky:
首先我们把所有串建一个AC自动机
方便起见我们直接把fail指针合并到子结点
如果一个串能无限长,也就是说它可以在AC自动机上一直进行匹配但就是匹配不上
也就是说匹配指针不能走到val为1的结点,设这个点为x
即root..x是一个病毒串
那么fail指针指向x的y也不能走
因为root..x是root..y的一个后缀
处理出来判断有向图是否有环
dfs即可
建fail时把那些当前节点i没有的字符(相当于失配状态)都转移到fail[i]上去,之后我们只要从根上出发dfs一通乱走,如果途中遇到字符串结束的标记节点,就不走(因为一走不就相当于有这个病毒了吗),如果最后无路可走(怎么选都要经过标记节点)那就NiE了,但如果我们能走出一个没有标记节点的环,那就说明我们可以找到一个循环节使字符串合法且无限延长下去了
注意:
DFS时注意及时退出,减少搜索树深度,用两个bool数组记录节点的搜索状态,其中一个表示这个点是否曾经搜索过,减少重复搜索;另一个表示这个点是否在我们目前想要的环的路径上(可能有点抽象,就是说我们是否已经经过这个点并且走在这个点所连接的边上,搜索完是要回溯的,而前一个bool数组只是单纯记录这个点是否走过,不必回溯更改)
代码:
#include<bits/stdc++.h>
using namespace std;
int root=1,tot=1,n;
int trie[30002][2],fail[30002];
bool num[30002],vis[30002],flag[30002];
char s[30002];
queue<int>q;
void insert(char s[])
{int len=strlen(s),now=root;for (int i=0;i<len;i++){if (!trie[now][s[i]-'0']) trie[now][s[i]-'0']=++tot;now=trie[now][s[i]-'0'];}num[now]=1;
}
void build()
{int now,tmp;q.push(root);while (!q.empty()){now=q.front();q.pop();for (int i=0;i<2;i++)if (trie[now][i]){tmp=fail[now];while (tmp&&!trie[tmp][i]) tmp=fail[tmp];if (tmp&&now!=root)fail[trie[now][i]]=trie[tmp][i],num[trie[now][i]]+=num[trie[tmp][i]];else fail[trie[now][i]]=root;q.push(trie[now][i]);}else{if (now==root) trie[now][i]=root;else trie[now][i]=trie[fail[now]][i];}}
}
void dfs(int x)
{if (flag[x]) {printf("TAK");exit(0);}if (num[x]||vis[x]) return;if (x!=root)vis[x]=1;flag[x]=1;for (int i=0;i<2;i++)dfs(trie[x][i]);flag[x]=0;
}
main()
{scanf("%d",&n);for (int i=1;i<=n;i++)scanf("%s",s),insert(s);build();dfs(root);printf("NIE");
}
【BZOJ2938】病毒,AC自动机练习相关推荐
- BZOJ2938[Poi2000]病毒——AC自动机
题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段,试问,是否 ...
- BZOJ2938: [Poi2000]病毒(AC自动机)
Orz wlp 5min讲完后缀数组 题意 给出$n$个0, 1串 问是否可以构造出一个无限长的字符串使其不包含任意串 Sol 刚开始我试图假装自己不知道这是个AC自动机的题然后来做.发现根本不可能q ...
- 洛谷 - P2444 - 病毒 - AC自动机
https://www.luogu.org/problemnew/show/P2444 有点恶心,不太明白fail的意义. #include<bits/stdc++.h> using na ...
- hdu 2896 病毒侵袭(AC自动机)
病毒侵袭 Time Limit: 2000/1000 ...
- bzoj 2938: [Poi2000]病毒(AC自动机)
2938: [Poi2000]病毒 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 1085 Solved: 541 [Submit][Status] ...
- HDOJ 2896 病毒侵袭(AC自动机入门)
题意: 求感染病毒的网站,并输出其感染的病毒特征码编号. 思路: AC自动机入门,思路同 HDOJ 2222 #include <iostream> #include <deque& ...
- bzoj2938(ac自动机)
刚学了ac自动机,去hzwer上找了道练习题: 串是安全的就说明ac自动机不会找到匹配,考虑ac自动机的匹配过程: 我们把val等于1的点删掉和fail指针指向被删掉的点删掉: 如果剩下的图有环,就有 ...
- HDU 2896 病毒侵袭 AC自动机
我表示不是很懂HDU卡内存的优良传统.......以及他们卡输出的良好风尚........ AC自动机裸体关键在于http://ascii.911cha.com/ #include<cstrin ...
- 【AC自动机】病毒代码(ybtoj AC自动机-5)
正题 ybtoj AC自动机-5 题目大意 给出若干段01串,问你是否存在一个无限的01串,使得串中不存在给出的01串 解题思路 可以把给出01串用AC自动机处理,然后对每个01串的最后一位打上标记 ...
最新文章
- JAVA_weB中的一些配置
- c语言两种加法,两个超长正整数的加法
- Dsp BootLoader的学习
- 在现有的python环境下创建另一个python版本【亲测有效】
- TreeViewVisitor: 一个快捷访问 TreeView 控件节点的帮助类
- Appium+python自动化(十六)- ADB命令,知否知否,应是必知必会(超详解)
- nodejs es6 中的单例模式
- AT1 one-dimensional objects
- linux过滤某个mac的包,macOS 下使用 tcpdump 抓包
- FastDFS单机、单节点和多节点集群部署文档
- 几种实用的pythonic语法
- 构建一个可行的BI系统的造价是多少,实施周期?具备条件基础是什么? 数据量有要求么
- pcs7 总结20170607
- 深度学习与计算机视觉教程(5) | 卷积神经网络(CV通关指南·完结)
- matlab中列主元三角分解法的函数,[数值算法]列主元三角分解法
- win7 命令行开启WiFi
- C#使用公共语言拓展(CLE)调用Python3(使用TensorFlow训练的模型)
- 海瑟矩阵和函数凹凸性之间的关系
- ​ios11自带邮件添加新的邮箱账号
- SUST Weekly Final Round One 参考题解
热门文章
- 用生动的案例一步步带你学会python多线程模块
- 本科阶段就挑战自动驾驶开发?华为云ModelArts帮你轻松实现!
- PyTorch官方教程中文版
- python让你再也不为文章配图与素材发愁,让高清图片占满你的硬盘! #华为云·寻找黑马程序员#
- Docker,使生信分析更简单、可重复
- mysql 变量被引号括住_【已解决】mysql中操作表的字段名时是否一定要用反引号括起来...
- 计算机一级专题训练,计算机等级考试一级MSOFFICE综合训练试题
- 基于Matlab的跨孔CT胖射线追踪算法(四)
- python replace函数后面的数字的含义
- LeetCode-114: 二叉树展开为链表