[Luogu P2444] [BZOJ 2938] [POI2000]病毒

版权声明:欢迎转载蒟蒻博客,但请注明出处: https://blog.csdn.net/LPA20020220/article/details/84289890

洛谷传送门

BZOJ传送门

题目描述

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

示例:

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

任务:

请写一个程序:

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

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

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

输入输出格式

输入格式:

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

输出格式:

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

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

NIE——如果不存在。

输入输出样例

输入样例#1:

3
01 
11 
00000

输出样例#1:

NIE

解题分析

一开始ZZ了, 然后发现把 f a i l fail 边加进来就是 A C AC 自动机上找环…

注意通过fail下传不能有的单词的标记。

代码如下:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#include <queue>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 100500
int cnt, root, n;
int fail[MX], son[MX][2];
bool tag[MX], vis[MX], ins[MX];
char buf[MX];
std::queue <int> q;
void insert()
{
	R int len = std::strlen(buf), now = root, id;
	for (R int i = 0; i < len; ++i)
	{
		id = buf[i] - '0';
		if (!son[now][id]) son[now][id] = ++cnt;
		now = son[now][id];
	}
	tag[now] = true;
}
void build()
{
	R int now;
	if (son[0][0]) q.push(son[0][0]);
	if (son[0][1]) q.push(son[0][1]);
	W (!q.empty())
	{
		now = q.front(); q.pop();
		for (R int i = 0; i < 2; ++i)
		{
			if (son[now][i])
			{
				fail[son[now][i]] = son[fail[now]][i];
				tag[son[now][i]] |= tag[fail[son[now][i]]];
				q.push(son[now][i]);
			}
			else son[now][i] = son[fail[now]][i];
		}
	}
}
void DFS(R int now)
{
	if (ins[now]) puts("TAK"), exit(0);
	if (vis[now]) return;
	vis[now] = ins[now] = true;
	if (!tag[son[now][0]]) DFS(son[now][0]);
	if (!tag[son[now][1]]) DFS(son[now][1]);
	ins[now] = false;
}
int main(void)
{
	scanf("%d", &n);
	W (n--) scanf("%s", buf), insert();
	build();
	DFS(0);
	puts("NIE");
}

猜你喜欢

转载自blog.csdn.net/LPA20020220/article/details/84289890