题目链接

题目描述

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

示例:

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

任务:

请写一个程序:

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

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

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

输入格式

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

输出格式

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

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

NIE——如果不存在。

输入输出样例

输入

3

01

11

00000

输出

NIE

分析

想办法让那串无限长的字符串不断的在树上失配,然后不断的走fail指针最后进入一个循环即可

即在树上dfs,保证不经过任何字符串尾节点使得找到一个树上环

AC code

#include <bits/stdc++.h>

using namespace std;

/*
* AC 自动机:多个模式串去匹配一个串,求有多少个模式串与主串有匹配内容
*
* 使用操作:
* 1、把每一个模式串插入到树中 insert
* 2、build
* 3、使用 query 询问有多少个模式串匹配
*/ const int CHAR_NUM = 2;//仅小写
const int MAXN = 2100;//模式串个数
const int MAXM = 30100;//模式串最长长度
const int NUM = MAXN * MAXM;//空间=个数*长度,稳 struct Trie {
int c[NUM][CHAR_NUM], val[NUM], fail[NUM], cnt; void insert(char *s) {
int len = strlen(s);
int now = 0;
for (int i = 0; i < len; i++) {
// int v = s[i] - 'a';
int v = s[i] - '0';
if (!c[now][v])c[now][v] = ++cnt;
now = c[now][v];
}
val[now]++;
} void build() {
queue<int> q;
for (int i = 0; i < CHAR_NUM; i++)if (c[0][i])fail[c[0][i]] = 0, q.push(c[0][i]);
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = 0; i < CHAR_NUM; i++)
if (c[u][i])fail[c[u][i]] = c[fail[u]][i], q.push(c[u][i]);
else c[u][i] = c[fail[u]][i];
}
} int query(char *s) {
int len = strlen(s);
int now = 0, ans = 0;
for (int i = 0; i < len; i++) {
// now = c[now][s[i] - 'a'];
now = c[now][s[i] - '0'];
for (int t = now; t && ~val[t]; t = fail[t])ans += val[t], val[t] = -1;
}
return ans;
}
} AC; char s[30100];
bool vis[NUM]; bool dfs(int cur) {
for (int i = 0; i < CHAR_NUM; ++i) {
int x = AC.c[cur][i];
if (!AC.val[x]) {
bool flag = false;
int t = x;
while (t) {
if (AC.val[t]) {
flag = true;
break;
}
t = AC.fail[t];
}
if (flag)
continue;
if (vis[x])
return true;
vis[x] = true;
if (dfs(x)) {
return true;
}
vis[x] = false;
}
}
return false;
} void solve() {
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> s;
AC.insert(s);
}
AC.build();
vis[0] = true;
bool flag = dfs(0);
if (flag) {
cout << "TAK" << endl;
} else {
cout << "NIE" << endl;
}
} int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
#ifdef ACM_LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
long long test_index_for_debug = 1;
char acm_local_for_debug;
while (cin >> acm_local_for_debug) {
cin.putback(acm_local_for_debug);
if (test_index_for_debug > 20) {
throw runtime_error("Check the stdin!!!");
}
auto start_clock_for_debug = clock();
solve();
auto end_clock_for_debug = clock();
cout << "Test " << test_index_for_debug << " successful" << endl;
cerr << "Test " << test_index_for_debug++ << " Run Time: "
<< double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
cout << "--------------------------------------------------" << endl;
}
#else
solve();
#endif
return 0;
}

【洛谷】P2444 [POI2000]病毒——AC自动机的更多相关文章

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

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

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

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

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

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

  4. [洛谷P2444] [POI2000]病毒

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

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

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

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

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

  7. 洛谷-P5357-【模板】AC自动机(二次加强版)

    题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但 ...

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

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

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

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

随机推荐

  1. Matlib’s lsqnonlin 和 scipy.optimize’s least_square

    matlib's lsqnonlin 和 scipy.optimize's least_square 问题 有三个点 $A,B,C$ , 经过一个线性变换 $T$ , 变为了 $A',B',C'$ 三 ...

  2. 7/8段码管(LED)

    LED显示器在许多的数字系统中作为显示输出设备,使用非常广泛.它的结构是由发光二极管构成的a.b.c.d.e.f和g七段,并由此得名,实际上每个LED还有一个发光段dp,一般用于表示小数点,所以也有少 ...

  3. Python 十大语法

    前言 Python 是一种代表简单思想的语言,其语法相对简单,很容易上手.不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了.本文精心筛选了最能展现 Python 语法之精妙的十个知识 ...

  4. Spring 事务传播机制和数据库的事务隔离级别

    Propagation(事务传播属性) 类别 传播类型 说明 支持当前事务 REQUIRED 如果当前没有事务,就新建一个事务.@Transaction的默认选择 支持当前事务 SUPPORTS 就以 ...

  5. 学习Vue.js-Day2

    书接上文/思考反馈 react,ng,vue作用差不多,那各个都有什么特点啊,实际工作中应该用哪一个? 答:其实在实际工作中,组员会通过讨论而选择框架:这三个框架都能解放你的工作量,也适合做单页面应用 ...

  6. ant tree 展开key的集合

    这次有个功能 ant的tree 展开 点击子节点 新增节点之后 数据能够照常展开 有几种方法 我能想到的 因为ant 有个expanded 只要设置为true就能展开了,但是这边有个陷阱,就是仅仅设置 ...

  7. Vue父子组件通讯

    我们知道,父组件不能修改子组件的数据[这种说法是不严谨的],严谨的说法是:子组件内部不能修改从父组件传递过来的值.原因是vue遵循的是数据单向流原则,父组件传递数据给子组件只能单向绑定,通过Props ...

  8. RabbitMQ面试题集锦(精选)(另附思维导图)

    1.使用RabbitMQ有什么好处? 1.解耦,系统A在代码中直接调用系统B和系统C的代码,如果将来D系统接入,系统A还需要修改代码,过于麻烦! 2.异步,将消息写入消息队列,非必要的业务逻辑以异步的 ...

  9. windows上用putty从linux上下载文件

    我之前使用putty都是直接从网上下的putty.exe,其实如果想下载windows的mis二进制文件,系统安装的话会包含,pscp.psftp.puttygen等一系列的文件. 今天下从服务器上, ...

  10. linux4.1.36 2440 启用 RTC 支持

    /drivers/rtc/rtc-s3c.c822行static struct platform_driver s3c_rtc_driver = {    .probe        = s3c_rt ...