2938: [Poi2000]病毒

Time Limit: 1 Sec  Memory Limit: 128 MB

Submit: 345  Solved: 176

[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

HINT

Source

这道题的思路非常好

首先我们跑一次AC自己主动机。Trie树和失配边就构成了一个有向图。那么,能找到一个无限长的安全代码,当且仅当在非单词节点中存在环。用拓扑排序推断就可以。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define pa pair<int,int>
#define maxn 30100
#define inf 1000000000
using namespace std;
struct edge_type
{
int next,to;
}e[maxn*2];
int go[maxn],in[maxn],head[maxn],t[maxn][2];
int n,tot=1,cnt=0;
bool v[maxn];
char s[maxn];
inline void add_edge(int x,int y)
{
e[++cnt]=(edge_type){head[x],y};
head[x]=cnt;
}
inline void insert()
{
scanf("%s",s);
int len=strlen(s),now=1;
F(i,0,len-1)
{
int x=s[i]-'0';
if (!t[now][x]) t[now][x]=++tot;
now=t[now][x];
}
v[now]=true;
}
inline void bfs()
{
queue<int> q;
q.push(1);
while (!q.empty())
{
int x=q.front(),y,j;q.pop();v[x]|=v[go[x]];
F(i,0,1)
{
j=go[x];
while (j&&!t[j][i]) j=go[j];
if (t[x][i])
{
go[y=t[x][i]]=j?t[j][i]:1;
q.push(y);
}
else t[x][i]=j? t[j][i]:1;
}
}
}
inline bool topsort()
{
queue<int> q;
int sum=0;
F(i,1,tot)
{
if (v[i]) sum++;
else F(j,0,1) if (!v[t[i][j]])
{
add_edge(i,t[i][j]);
in[t[i][j]]++;
}
}
F(i,1,tot) if (!v[i]&&!in[i]) q.push(i);
while (!q.empty())
{
int x=q.front();q.pop();sum++;
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
in[y]--;
if (!in[y]) q.push(y);
}
}
return sum==tot;
}
int main()
{
scanf("%d",&n);
F(i,1,n) insert();
bfs();
printf("%s\n",topsort()? "NIE":"TAK");
return 0;
}

bzoj2938【Poi2000】病毒的更多相关文章

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

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

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

    2938: [Poi2000]病毒 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 1678  Solved: 849[Submit][Status][D ...

  3. BZOJ2938 [Poi2000]病毒 和 BZOJ5261 Rhyme

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

  4. bzoj2938: [Poi2000]病毒

    建AC自动机,把所有病毒的节点都删掉,dfs判有没有环,有环就找得到. #include <iostream> #include <cstdio> #include <c ...

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

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

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

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

  7. BZOJ2938 [Poi2000]病毒 【AC自动机】

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

  8. BZOJ2938 POI2000病毒

    我们不能让重复过的字串出现在无限串上(就叫这个了...) 也就是要自动机一直能匹配但就是匹配不到,那么就是在自动机上找一个环. dfs判环即可.注意是个有向图. #include<bits/st ...

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

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

  10. 【BZOJ-2938】病毒 Trie图 + 拓扑排序

    2938: [Poi2000]病毒 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 609  Solved: 318[Submit][Status][Di ...

随机推荐

  1. python-网络-udp

    python-网络-udp 标签(空格分隔): python 开发环境:windows Pycharm+python3.* 工具:网络调试助手 UDP[client]-发送数据 from socket ...

  2. 关于ios11和Chrome浏览器非HTTPS 对高德定位不支持问题

    最近,在开发二维码签到系统时,需要对用户的签到的经纬度进行获取,并且判断签到距离是否在可支持范围内. 使用了高德地图.因为本人最近刚刚入手了一款新的Iphone7里面是最新的ios11系统.发现我的手 ...

  3. d3碰撞源码分析

    技术 d3. d3.force.d3.geom.quadtree. d3.geom.quadtree 四叉树的应用:图像处理.空间数据索引.2D中的快速碰撞检测.存储稀疏数据等,游戏编程. 上图中的数 ...

  4. 欢迎访问微先锋vXianFeng官方博客

    欢迎访问微先锋vXianFeng官方博客,专注微商城.P2P理财.山寨矿机平台研究与开发!

  5. Python学习笔记(4)--数据结构之元组tuple

    元组(tuple) 定义:tuple和list十分相似,但是tuple是不可变的,即不能修改tuple 初始化:(), ('a', ) , ('a', 'b')   //当只有一个元素时,需加上逗号, ...

  6. CRC校验原理及步骤

    什么是CRC校验? CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并 ...

  7. intellij idea中快速抽取方法

    Intellij Idea使用教程汇总篇 问题:有时候一个方法里面嵌套了很多逻辑,想拆分为多个方法方便调用:或者一个方法复用性很高,这时,这个方法嵌套在局部方法里面肯定是不方便的,如何快速抽取出这个方 ...

  8. HBase快照、Snapshots 淘宝快照

    淘宝在2011年之前所有的后端持久化存储基本上与我们所认知的意义,  大量存于 mysql .少量 oracle mongdb 等,使用mysql 的原因相信各位也很熟悉了.  开源.社区庞大.解决方 ...

  9. POJ - 3415 Common Substrings(后缀数组求长度不小于 k 的公共子串的个数+单调栈优化)

    Description A substring of a string T is defined as: T( i, k)= TiTi+1... Ti+k-1, 1≤ i≤ i+k-1≤| T|. G ...

  10. vue23:vue-loader

    vue-loader: 其他loader -> css-loader.url-loader.html-loader..... 后台: nodeJs(模块化) -> require expo ...