题目

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

示例:

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

任务:

请写一个程序:

l 读入病毒代码;

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

l 将结果输出

输入格式

第一行包括一个整数n,表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。

输出格式

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

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

l NIE——如果不存在。

输入样例

3

01

11

00000

输出样例

NIE

题解

我们对所有串建出一个ACM,我们要做的就是在ACM上找一个路径,使得路径包含环且不包含结束节点

对于所有fail指针指向的节点,如果形成串,那么该节点也不能选,因为fail指针指向的为当前串的前缀

建完机后跑一跑dfs检查环就好了

#include<iostream>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 300005,maxm = 1000005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
int ch[maxn][2],siz,fail[maxn],val[maxn];
char s[maxn];
void insert(char* P){
int u = 0,len = strlen(P),x;
for (int i = 0; i < len; i++){
x = P[i] - '0';
if (!ch[u][x]) ch[u][x] = ++siz;
u = ch[u][x];
}
val[u] = 1;
}
void getfail(){
queue<int> q; fail[0] = -1;
for (int i = 0; i < 2; i++) if (ch[0][i]) q.push(ch[0][i]);
int u;
while (!q.empty()){
u = q.front(); q.pop();
for (int i = 0; i < 2; i++){
int v = ch[u][i];
if (!v) {ch[u][i] = ch[fail[u]][i]; continue;}
int k = fail[u];
fail[v] = ch[k][i];
val[v] |= val[ch[k][i]];
q.push(v);
}
}
}
bool flag;
int vis[maxn],ins[maxn];
bool dfs(int u){
ins[u] = true;
for (int i = 0; i < 2; i++){
int v = ch[u][i];
if (ins[v]) return true;
if (vis[v] || val[v]) continue;
vis[v] = true;
if (dfs(v)) return true;
}
ins[u] = false;
return false;
}
int main(){
int n = read();
while (n--) scanf("%s",s),insert(s);
getfail();
dfs(0) ? puts("TAK") : puts("NIE");
return 0;
}

BZOJ2938 [Poi2000]病毒 【AC自动机】的更多相关文章

  1. BZOJ2938[Poi2000]病毒——AC自动机

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

  2. BZOJ2938:[POI2000]病毒(AC自动机)

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

  3. 【BZOJ2938】[Poi2000]病毒 AC自动机+DFS

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

  4. 【bzoj2938】[Poi2000]病毒 AC自动机

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

  5. [bzoj2938][Poi2000]病毒_AC自动机

    病毒 bzoj-2938 Poi-2000 题目大意:给你n个01串,问是否存在一个无限长的01串使得这个01的任意子串都不等于给出的01串. 注释:All_length<=30,000 想法: ...

  6. [POI2000]病毒 --- AC自动机

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

  7. BZOJ 2938: [Poi2000]病毒 [AC自动机 拓扑排序]

    2938: [Poi2000]病毒 题意:判断是否存在无限长的不含模式串的字符串.只有01. 建出套路DP的转移图,判断有环就行了 练习一下拓扑排序 #include <iostream> ...

  8. BZOJ [Poi2000]病毒 AC自动机_DFS_细节

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) # ...

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

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

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

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

随机推荐

  1. JS给数字加千位分隔符

    本文原链接:https://www.jianshu.com/p/928c68f92c0c JavaScript实现千位分隔符 将普通的数字转换为带千位分隔符格式的数字字符串是一个非常常见的问题,千位分 ...

  2. 第二单元OO总结

    目录 前言 一.第一次作业分析 1. UML及复杂度分析 二.第二次作业分析 1. UML及复杂度分析 2. 性能优化 2.1 楼层类的实现 2.2 调度算法 3. bug分析 三.第三次作业分析 1 ...

  3. JavaScript无提示关闭当前页面窗口,兼容IE/Firefox/Chrome

    <script type="text/javascript" language="javascript"> function fc(){ var b ...

  4. Spring Security 与 OAuth2(介绍)

    https://www.jianshu.com/p/68f22f9a00ee Spring Security 与 OAuth2(介绍) 林塬 2018.01.23 11:14* 字数 3097 阅读 ...

  5. Protobuf有没有比JSON快5倍?用代码来击破pb性能神话

    转 http://www.sohu.com/a/136487507_505779 2017-04-26 07:58 程序设计 /58 /技术 导读:Google 的 Protocol Buffers ...

  6. 使用kickstart + pxe 部署无人值守安装

    1.作为中小公司的运维,经常会遇到一些机械式的重复工作,例如:有时公司同时上线几十甚至上百台服务器,而且需要我们在短时间内完成系统安装. 常规的安装系统方法: 光盘安装系统:一个服务器DVD内置光驱百 ...

  7. virtualbox安装win7系统报错(“FATAL:No bootable medium found!”)

    virtualbox属于傻瓜式安装虚拟系统,但博主安装win7系统时,无论怎么调试都还是出现截图所述样式,网上教程很多,但是都不行,其实只有一个根本原因安装的iso镜像不是原生镜像,下载的镜像已经是被 ...

  8. C++中重载、覆盖和隐藏的区别,以及适用场景

    一.重载.覆盖和隐藏的区别 二.适用场景 1.重载: 适用于不同的数据类型都需要使用到的功能函数.以数据相加的函数为例,可以在同一个文件内提供以下的重载函数以支持同样的功能: int add(int, ...

  9. 给vagrant中的precise64升级VBoxGuestAdditions

    位置:/usr/share/virtualbox/VBoxGuestAdditions.iso 在host(ubuntu 12.04 64)中: 查看虚拟机的名字:jb@H38:~/vm/vagran ...

  10. SQL_3_表达式、条件语句与运算

    加号的两种用法: 1.在SELECT子句中使用+号以执行对数据的运算并将结果显示出来. SELECT ITEM WHOLESALE WHOLESALE+0.15 FROM PRICE; 还可以重命名新 ...