zoukankan      html  css  js  c++  java
  • BZOJ 2938: [Poi2000]病毒

    2938: [Poi2000]病毒

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 693  Solved: 360
    [Submit][Status][Discuss]

    Description

    二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。
    示例:
    例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。
    任务:
    请写一个程序:
    l         读入病毒代码;
    l         判断是否存在一个无限长的安全代码;
    l         将结果输出

    Input

     
    第一行包括一个整数n,表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。

    Output

    你应在在文本文件WIN.OUT的第一行输出一个单词:
    l         TAK——假如存在这样的代码;
    l         NIE——如果不存在。

    Sample Input

    3
    01
    11
    00000

    Sample Output

    NIE

    HINT

     

    Source

     
    [Submit][Status][Discuss]

    在AC自动机上找不经过dangerous点的环。

     1 #include <cstdio>
     2 
     3 int tail = 1;
     4 int dang[50005];
     5 int fail[50005];
     6 int next[50005][2];
     7 
     8 inline void insert(char *s)
     9 {
    10     int t = 1; 
    11     
    12     for (; *s; ++s)
    13     {
    14         int c = *s - '0';
    15         
    16         if (next[t][c] == 0)
    17             next[t][c] = ++tail;
    18         
    19         t = next[t][c];
    20     }
    21     
    22     dang[t] = true;    //dangerous node
    23 }
    24 
    25 inline void preworkFail(void)
    26 {
    27     static int que[100005], l, r;
    28     
    29     fail[que[l = 0] = r = 1] = 0;
    30     
    31     while (l != r)
    32     {
    33         int u = que[l++];
    34         
    35         for (int i = 0; i < 2; ++i)
    36         {
    37             if (next[u][i] == 0)
    38                 next[u][i] = next[fail[u]][i];
    39             else
    40             {
    41                 int t = fail[u];
    42                 
    43                 while (next[t][i] == 0)
    44                     t = fail[t];
    45                 
    46                 fail[next[u][i]] = next[t][i];
    47                 
    48                 if (dang[next[t][i]])
    49                     dang[next[u][i]] = true;
    50                 
    51                 que[r++] = next[u][i];
    52             }
    53         }
    54     }
    55 }
    56 
    57 bool vis[50005];
    58 bool ins[50005];
    59 
    60 bool findCircle(int u)
    61 {
    62     ins[u] = true;
    63     
    64     for (int i = 0, v; i < 2; ++i)
    65         if (v = next[u][i])
    66         {
    67             if (ins[v])return true;
    68             if (vis[v] || dang[v])continue;
    69             if (findCircle(v))return true;
    70         }
    71     
    72     vis[u] = true;
    73     ins[u] = false;
    74     
    75     return false;
    76 }
    77 
    78 signed main(void)
    79 {
    80     static int n;
    81     static char str[30005];
    82     
    83     scanf("%d", &n);
    84     
    85     next[0][1] = next[0][0] = 1;
    86     
    87     for (int i = 1; i <= n; ++i)
    88         scanf("%s", str), insert(str);
    89     
    90     preworkFail();
    91     
    92     puts(findCircle(1) ? "TAK" : "NIE");
    93 }

    @Author: YouSiki

  • 相关阅读:
    【LeetCode题解】844_比较含退格的字符串(Backspace-String-Compare)
    【LeetCode题解】25_k个一组翻转链表(Reverse-Nodes-in-k-Group)
    【LeetCode题解】24_两两交换链表中的节点(Swap-Nodes-in-Pairs)
    【LeetCode题解】347_前K个高频元素(Top-K-Frequent-Elements)
    【LeetCode题解】19_删除链表的倒数第N个节点(Remove-Nth-Node-From-End-of-List)
    【LeetCode题解】61_旋转链表(Rotate-List)
    IdentityServer4密码模式接入现有用户数据表
    .Net Core Swagger:Actions require an explicit HttpMethod binding for Swagger 2.0
    ABP缓存
    ABP仓储
  • 原文地址:https://www.cnblogs.com/yousiki/p/6281959.html
Copyright © 2011-2022 走看看