题目描述

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

示例:

例如如果{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. android Menu 笔记

    菜单是应用中常见的用户组件.本文介绍如何在布局文件和代码中添加menu,submenu以及在代码中添加的方法. 参考链接 https://developer.android.com/guide/top ...

  2. VC++使用CSocket发送HTTP Request时需要注意发送数据的编码格式

    VS2010以及更高版本中新建的MFC项目字符集默认是Unicode,CString创建的字符串默认是Unicode. 使用CSocket时,若以CString组织需要发送的HTTP Head时,那么 ...

  3. Java调用FTP实例

    package com.test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStre ...

  4. js中页面跳转(href)中文参数传输方式

    编码: escape(参数); 解码: unescape(参数);

  5. iOS开发- UILabel 自己主动换行 及 高度自适应

    主要是今天看到论坛有人问这个问题.帮忙解决之后, 顺便Mark下. 非常easy, 代码写的非常清楚. 直接上代码. UILabel *label = [[UILabel alloc] initWit ...

  6. About {DynamicResource {x:Static SystemColors.ControlBrushKey}}

    from : http://blog.sina.com.cn/s/blog_749e42850100sahi.html 前提: <system:String x:Key="{Compo ...

  7. 双十二“MathType”限时6折特惠

    MathType是由美国Design Science公司开发功能强大的公式编辑器,专门用来对数学公式的编辑,与常见的文字处理软件和演示程序配合使用,能够在各种文档中加入复杂的数学公式和符号.双十二期间 ...

  8. Fast-RCNN

    后面框架回归和分类都放到了神经网络里 测试速度提升100倍 训练10

  9. 如何通过XAMPP来实现单个服务器上建多个网站

    xampp 是一个非常方便的本地 apache + php + mysql 的调试环境,在本地安装测试 WordPress 等各种博客.论坛程序非常方便.今天我们来给大家介绍一下,如何使用 XAMPP ...

  10. JQuery------jQuery.parseHTML()的使用方法

    代码: $(document).ready(function () { var data = jQuery.parseHTML("<p>你好</p>"); ...