题目描述

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

示例:

例如如果{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——如果不存在。

输入输出样例

输入样例#1: 复制

3
01
11
00000
输出样例#1: 复制

NIE

题意:

给n个模式串,问能不能找到一个无限长的文本串,使得模式串没有出现在文本串里。

思路:

看到题目没想法......看了题解

我们会发现正常的AC自动机都是在文本串中去匹配模式串,现在不要模式串出现,那么也就是说希望Trie中被标记为模式串结尾的节点不要出现。我们将这个称为危险标记。而想要无限长的文本串,其实也就是在匹配过程中能否找到这样一个环,使得环上的节点都是安全的。

首先我们还是先建立fail数组,需要注意的是,如果一个节点的fail指针指向的节点是危险的,那么他本身也是危险的。

因为一个节点x的fail指针指向的节点y表示的是以y作为结尾的前缀与以x为结尾的前缀的后缀匹配的最长部分,也就是说根节点到y一定是在根节点到x中出现过的。

然后dfs,用一个数组vis标记路径,一个数组f标记是否访问过。vis在dfs结束后要恢复,是用来判断当前路径是否形成环的。

 #include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f int n;
const int maxn = ; struct Tree{
int fail;//失配指针
int vis[];//子节点位置
int ed;//标记有几个单词以这个节点结尾
}AC[maxn];
string s;
int tot = ; void build(string s)
{
int len = s.length();
int now = ;//字典树当前指针
for(int i = ; i < len; i++){
if(AC[now].vis[s[i] - ''] == ){
AC[now].vis[s[i] - ''] = ++tot;
}
now = AC[now].vis[s[i] - ''];
}
AC[now].ed = ;
} void get_fail()
{
queue<int> que;
for(int i = ; i < ; i++){
if(AC[].vis[i] != ){
AC[AC[].vis[i]].fail = ;
que.push(AC[].vis[i]);
}
}
while(!que.empty()){
int u = que.front();
que.pop();
for(int i = ; i < ; i++){
if(AC[u].vis[i] != ){
AC[AC[u].vis[i]].fail = AC[AC[u].fail].vis[i];
if(AC[AC[u].fail].ed){
AC[u].ed = ;
}
que.push(AC[u].vis[i]);
}
else{
AC[u].vis[i] = AC[AC[u].fail].vis[i];
}
}
}
} bool vis[maxn], f[maxn];
void dfs(int rt)
{
vis[rt] = true;
for(int i = ; i < ; i++){
if(vis[AC[rt].vis[i]]){
printf("TAK\n");
exit();
}
else if(!AC[AC[rt].vis[i]].ed && !f[AC[rt].vis[i]]){
f[AC[rt].vis[i]] = true;
dfs(AC[rt].vis[i]);
}
}
vis[rt] = false;
} int main()
{
scanf("%d", &n);
for(int i = ; i < n; i++){
cin>>s;
build(s);
}
AC[].fail = ;
get_fail();
dfs();
printf("NIE\n");
//cout<<s[maxid]<<endl;
//cout<<AC_query(s)<<endl;
return ;
}

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

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

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

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

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

  3. 洛谷 - P3966 - 单词 - AC自动机

    https://www.luogu.org/problemnew/show/P3966 因为文本串就是字典本身,所以这个和平时的AC自动机不太一样.平时的query要沿着fail树把子树的出现次数依次 ...

  4. 洛谷P3808 & P3796 AC自动机模板

    题目:P3808:https://www.luogu.org/problemnew/show/P3808 P3796:https://www.luogu.org/problemnew/show/P37 ...

  5. 洛谷.3121.审查(AC自动机 链表)

    题目链接 //删掉一个单词需要前移一段位置,用链表维护就好了 复杂度O(sum(len)) #include <cstdio> #include <cstring> #defi ...

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

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

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

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

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

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

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

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

随机推荐

  1. Spring 4 官方文档学习(十一)Web MVC 框架之resolving views 解析视图

    接前面的Spring 4 官方文档学习(十一)Web MVC 框架,那篇太长,故另起一篇. 针对web应用的所有的MVC框架,都会提供一种呈现views的方式.Spring提供了view resolv ...

  2. HEVC/H.265 的未来必须是使用并行处理(OpenCL?) OpenCV和OpenCL区别

    1 扩展库简介 OpenCV(Open Source Computer Vision Library)是一个致力于实时处理计算机视觉问题的开源库.它最初由Intel公司开发,以GPL许可协议发布,后来 ...

  3. android 自定义照相机Camera黑屏 (转至 http://blog.csdn.net/chuchu521/article/details/8089058)

    对于一些手机,像HTC,当自定义Camera时,调用Camera.Parameters的 parameters.setPreviewSize(width, height)方法时,如果width和hei ...

  4. NPOI帮助类(Excel转DataTable、DataTable转Excel)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using NPOI.SS. ...

  5. Linux jstack分析cpu占用100%

    背景: 运行测试程序后,top命令发现某个进程(pid)占用cpu达到100%.   查看哪个线程占用最多资源: ps mp pid -o THREAD,tid,命令查看这个进程下面的所有线程占用情况 ...

  6. url传参错误的痛

    今天用一下方法给后台传参数: var url = 'patrolpoint!totalHistoryPage.action' +        '?patrolPoint.batchOnTime=' ...

  7. UGUI 的多分辨率适配

    1.Canvas的属性配置 2.Canvas Scaler的属性配置 3.根据不同的屏幕的比例动态修改缩放基准 void Start () { float standard_width = 960f; ...

  8. jquery插件大全

    241个jquery插件—jquery插件大全 免费JQuery插件 推荐12款非常有用的流行 jQuery 插件

  9. MySQL<事务与存储过程>

    事务与存储过程 事务管理 事务的概念 谓的事务就是针对数据库的一组操作,它可以由一条或多条SQL语句组成,同一个事务的操作具备同步的特点,即事务中的语句要么都执行,要么都不执行. 事务的使用 开启事务 ...

  10. php学习三:函数

    1.  php中的函数和js中的区别 在php中,函数的形参可以给一个默认值,若有实参的传递则函数使用传递过来的参数,没有的话显示默认值 代码如下: function showSelf($name=& ...