zoukankan      html  css  js  c++  java
  • [AC自动机][dfs] 洛谷 P2444 病毒

    题目描述

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

    示例:

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

    任务:

    请写一个程序:

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

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

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

    输入输出格式

    输入格式:

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

    输出格式:

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

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

    NIE——如果不存在。

    输入输出样例

    输入样例#1:
    3
    01 
    11 
    00000
    
    输出样例#1:
    NIE

    题解

    • 题目大意是要求是否有没有被匹配的无限长代码
    • 这题有点奇怪,求的无限长代码
    • 那么就是要一直失配,那么可以将fail边(失配边)当成原树边来做
    • 这样的话,其实就是要在trie树上求没有匹配的字串的一个环,dfs做

    代码

     1 #include <cstdio> 
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <queue>
     6 using namespace std;
     7 bool vis[30010],g[30010];
     8 char ch[30010];
     9 int n,cnt,f[30010][4];
    10 queue<int> Q;
    11 void insert(char ch[],int len)
    12 {
    13     int p=0;
    14     for (int i=1;i<=len;i++)
    15         if (f[p][ch[i]-'0']==0) f[p][ch[i]-'0']=++cnt,p=cnt;
    16         else p=f[p][ch[i]-'0'];
    17     f[p][2]=true;
    18 }
    19 void getfail()
    20 {
    21     if (f[0][0]>0) Q.push(f[0][0]);
    22     if (f[0][1]>0) Q.push(f[0][1]);
    23     while (!Q.empty())
    24     {
    25         int u=Q.front(); Q.pop();
    26         for (int i=0;i<=1;i++)
    27             if (f[u][i]>0)
    28             {
    29                 Q.push(f[u][i]);
    30                 int v=f[u][3];
    31                 while (v&&f[v][i]<=0) v=f[v][3];
    32                 if (f[v][i]<=0) f[f[u][i]][3]=0;
    33                 else
    34                 {
    35                     f[f[u][i]][3]=f[v][i];
    36                     if (f[f[v][i]][2]) f[f[u][i]][2]=true;
    37                 }
    38             }
    39             else f[u][i]=f[f[u][3]][i];
    40     }
    41 }
    42 void dfs(int x)
    43 {
    44     vis[x]=true;
    45     for (int i=0;i<=1;i++)
    46         if (vis[f[x][i]]) { printf("TAK"); exit(0); }
    47         else
    48             if (!f[f[x][i]][2]&&!g[f[x][i]]) g[f[x][i]]=true,dfs(f[x][i]);
    49     vis[x]=false;
    50 }
    51 int main()
    52 {
    53     scanf("%d",&n);
    54     for (int i=1;i<=n;i++) scanf("%s",ch+1),insert(ch,strlen(ch+1));
    55     getfail();
    56     dfs(0);
    57     printf("NIE");
    58 }
  • 相关阅读:
    推荐系统 蒋凡译 第一章 引言 读书笔记
    神经网络与深度学习 邱锡鹏 第5章 卷积神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第4章 前馈神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第3章 线性模型 读书笔记
    神经网络与深度学习 邱锡鹏 第2章 机器学习概述 读书笔记
    神经网络与深度学习 邱锡鹏 第1章 绪论 作业
    神经网络与深度学习 邱锡鹏 第1章 绪论 读书笔记
    算法笔记 上机训练实战指南 第13章 专题扩展 学习笔记
    算法笔记 第13章 专题扩展 学习笔记
    算法笔记 上机训练实战指南 第11章 提高篇(5)--动态规划专题 学习笔记
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9807056.html
Copyright © 2011-2022 走看看