洛谷题目链接:[POI2000]病毒

题目描述

二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。

示例:

例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。

任务:

请写一个程序:

1.在文本文件WIR.IN中读入病毒代码;

2.判断是否存在一个无限长的安全代码;

3.将结果输出到文件WIR.OUT中。

输入输出格式

输入格式:

在文本文件WIR.IN的第一行包括一个整数n(n≤2000)(n\le 2000)(n≤2000),表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。

输出格式:

在文本文件WIR.OUT的第一行输出一个单词:

TAK——假如存在这样的代码;

NIE——如果不存在。

输入输出样例

输入样例#1:

3

01

11

00000

输出样例#1:

NIE

题解: 显然我们是无法枚举一个无限长的串的,那么我们需要考虑找到这个构造方法.

既然是多模式串匹配,这里我们考虑使用\(AC\)自动机.

首先还是先建出\(AC\)自动机,然后我们考虑如何才能找到一个不被匹配的方法.我们知道如果匹配就是在\(AC\)自动机中访问到一个标记过的节点,或是该串的前缀中含有单词,所以我们可以在建树的过程中将有单词的点都打上标记,并且将它的所有子节点都打上标记,表示访问到这些节点就不存在合法答案.

那么如何找合法答案呢?因为在\(AC\)自动机上的匹配过程需要通过\(fail\)指针来跳转,所以如果能找到一个包含\(0\)节点(\(trie\)起始的空节点)的环,那么就可以一直在这个环上跳转一直不匹配成功,直接用\(dfs\)来找这个环就可以了.

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 3e4+5;
  4. int n, cntn, ch[2][N], fail[N], chk[N], vis[N];
  5. bool ok[N];
  6. char s[N];
  7. void insert(char *s){
  8. int len = strlen(s+1), now = 0;
  9. for(int i = 1; i <= len; i++){
  10. if(!ch[s[i]-'0'][now]) ch[s[i]-'0'][now] = ++cntn;
  11. now = ch[s[i]-'0'][now];
  12. }
  13. ok[now] = 0;
  14. }
  15. void build(){
  16. queue <int> q;
  17. if(ch[0][0]) q.push(ch[0][0]);
  18. if(ch[1][0]) q.push(ch[1][0]);
  19. while(!q.empty()){
  20. int x = q.front(); q.pop();
  21. for(int i = 0; i < 2; i++){
  22. if(ch[i][x]){
  23. fail[ch[i][x]] = ch[i][fail[x]];
  24. q.push(ch[i][x]);
  25. ok[ch[i][x]] &= ok[ch[i][fail[x]]];
  26. }
  27. else ch[i][x] = ch[i][fail[x]];
  28. }
  29. }
  30. }
  31. void dfs(int x){
  32. if(vis[x]) cout << "TAK" << endl, exit(0);
  33. if(chk[x] || !ok[x]) return;
  34. vis[x] = chk[x] = 1;
  35. dfs(ch[0][x]), dfs(ch[1][x]);
  36. vis[x] = 0;
  37. }
  38. int main(){
  39. cin >> n;
  40. memset(ok, 1, sizeof(ok));
  41. for(int i = 1; i <= n; i++) cin >> s+1, insert(s);
  42. build();
  43. dfs(0);
  44. cout << "NIE" << endl;
  45. return 0;
  46. }

[洛谷P2444] [POI2000]病毒的更多相关文章

  1. 洛谷 P2444 [POI2000]病毒 解题报告

    P2444 [POI2000]病毒 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已 ...

  2. 洛谷P2444 [POI2000]病毒(AC自动机,DFS求环)

    洛谷题目传送门 AC自动机入门--yyb巨佬的博客 AC自动机入手经典好题(虽然年代久远) 有了fail指针,trie树就不是原来的树型结构了,我们可以把它叫做trie图,由父节点向子节点连的边和fa ...

  3. P2444 [POI2000]病毒

    P2444 [POI2000]病毒 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已 ...

  4. P2444 [POI2000]病毒 AC自动机

    P2444 [POI2000]病毒 #include <bits/stdc++.h> using namespace std; ; struct Aho_Corasock_Automato ...

  5. 【洛谷 P2444】 [POI2000]病毒(AC自动机)

    题目链接 这么多字符串,肯定是自动机啦. 先建出AC自动机,然后怎么表示一个安全代码没有病毒代码呢? 就是存在一条路径不经过有病毒代码段结尾的节点呗. 所以呢?有环啊!dfs一下救星了. #inclu ...

  6. 【洛谷】P2444 [POI2000]病毒——AC自动机

    题目链接 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段, ...

  7. 洛谷P2444 病毒 [POI2000] AC自动机

    正解:AC自动机 解题报告: 传送门! 首先看到这种题目二话不说先把trie树和fail指针建立起来 然后就想鸭,如果我们想让模式串和文本串尽量不能匹配,就要想办法让它跳fail指针,而不是继续往下走 ...

  8. 洛谷 - P2444 - 病毒 - AC自动机

    https://www.luogu.org/problemnew/show/P2444 有点恶心,不太明白fail的意义. #include<bits/stdc++.h> using na ...

  9. 洛谷P2444 病毒【AC自动机】

    题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段,试问,是否 ...

随机推荐

  1. Linux(Red hat)无网离线安装TensorFlow

    文件下载 首先,下载想要安装的版本,目前最新的是1.8.0 根据你的python版本下载对应的whl文件,下载连接:https://pypi.org/project/tensorflow/#files ...

  2. 24_IO_第24天(转换流、缓冲流)_讲义

    今日内容介绍 1.转换流 2.缓冲流 01转换流概述 * A: 转换流概述 * a: 转换流概述 * OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流 ...

  3. 如何查看Maven项目的jar包依赖

    问题 十年以前写java项目总会干这么一个事情: 调包. java项目往往依赖了很多第三方jar包,而这些jar包又有他自己依赖的第三方jar包,从而就能形成一个依赖树. 而程序运行要把这些所有的依赖 ...

  4. JPEG标准推荐的亮度、色度DC、AC Huffman编码表

    JPEG 标准推荐的亮度.色度DC.AC Huffman 编码表 博主在完成数字图像处理大作业时利用搜索引擎查找了很久完整的四张Huffman 编码表(亮度AC Huffman编码表.亮度DC Huf ...

  5. 第九周(11.11-11.17)----Beta版本发布140字评论

    1.新蜂组: 俄罗斯方块:项目有良好的用户界面,在原版的基础上可以对用户分数进行排序,增加了显示下一个方块的功能.是个很有趣的小游戏. 2.天天向上组: 连连看:完成了基本功能,增加了消除时和鼠标点击 ...

  6. Mysql 数据锁与事务

    一.锁 常用命令 查看表的存储引擎:mysql> show create table myLock; 修改当前表的存储引擎:mysql> alter table myLock engine ...

  7. PHP中测试in_array、isset、array_key_exists性能

    测试in_array.isset.array_key_exists性能.自己写的简易测试代码: ini_set('display_errors',true); error_reporting(E_AL ...

  8. SPOJ_SUBLEX

    经典题目:给一个字符串,求字典序第k小的子串是什么. 涉及子串问题,上自动机. 首先我们可以用记忆化搜索的方法,求出到达某一个状态后,能产生多少个新状态. 首先,到达这个状态就不走了,这肯定是一种状态 ...

  9. mysql二进制日志的开启和使用

    二进制日志(BINLOG)记录了所有的ddl和dml语句,但不包括数据查询语句.语句以“事件”的形式保存,描述数据更改过程. 环境:win8   mysql5.6.23 1.mysql开启二进制日志 ...

  10. kiki's game HDU - 2147(找规律)

    #include"stdio.h" int main( ) { int n,m; ||m!=)) { ==||m%==) printf("Wonderful!\n&quo ...