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

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 993  Solved: 500
    [Submit][Status][Discuss]

    Description

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

    示例:

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

    任务:

    请写一个程序:

    1. 读入病毒代码;
    2. 判断是否存在一个无限长的安全代码;
    3. 将结果输出

    Input

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

    Output

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

    1. TAK——假如存在这样的代码;
    2. NIE——如果不存在。

    Sample Input

    3
    01
    11
    00000

    Sample Output

    NIE

    思路

    AC自动机+拓扑序列;

    代码实现

     1 #include<cstdio>
     2 const int maxn=3e4+10;
     3 int n;
     4 char ch[maxn];
     5 int next[maxn][2],fail[maxn],sz=2;
     6 bool end[maxn];
     7 void ins(){
     8     int a;
     9     scanf("%s",ch);
    10     for(int i=0,j=0;;i++){
    11         if(!ch[i]){end[j]=1;break;}
    12         a=ch[i]-'0';
    13         if(!next[j][a]) next[j][a]=++sz;
    14         j=next[j][a];
    15     }
    16 }
    17 int q[maxn],head,tail;
    18 void build(){
    19     int a,b;
    20     head=0,tail=2;
    21     q[0]=1,q[1]=2;
    22     while(head<tail){
    23         a=q[head++];
    24         if(next[a][0]){
    25             b=fail[a];
    26             while(!next[b][0]) b=fail[b];
    27             fail[next[a][0]]=next[b][0];
    28             if(end[next[b][0]]) end[next[a][0]]=1;
    29             q[tail++]=next[a][0];
    30         }
    31         else next[a][0]=next[fail[a]][0];
    32         if(next[a][1]){
    33             b=fail[a];
    34             while(!next[b][1]) b=fail[b];
    35             fail[next[a][1]]=next[b][1];
    36             if(end[next[b][1]]) end[next[a][1]]=1;
    37             q[tail++]=next[a][1];
    38         }
    39         else next[a][1]=next[fail[a]][1];
    40     }
    41 }
    42 int tot;
    43 int point[maxn],nxt[maxn<<1],v[maxn<<1],in[maxn];
    44 bool vis[maxn];
    45 void add(int x,int y){tot++,nxt[tot]=point[x],point[x]=tot,v[tot]=y;}
    46 void dfs(int k){
    47     vis[k]=1;
    48     add(k,next[k][0]);in[next[k][0]]++;
    49     if(!vis[next[k][0]]&&!end[next[k][0]]) dfs(next[k][0]);
    50     add(k,next[k][1]);in[next[k][1]]++;
    51     if(!vis[next[k][1]]&&!end[next[k][1]]) dfs(next[k][1]);
    52 }
    53 bool f_ring(){
    54     int cnt=0,a;
    55     head=tail=0;
    56     for(int i=0;i<sz;i++) if(!in[i]) q[tail++]=i;
    57     while(head<tail){
    58         a=q[head++],cnt++;
    59         for(int i=point[a];i;i=nxt[i]){
    60             in[v[i]]--;
    61             if(!in[v[i]]) q[tail++]=v[i];
    62         }
    63     }
    64     return cnt<sz;
    65 }
    66 int main(){
    67     scanf("%d",&n);
    68     next[0][0]=1,next[0][1]=2;
    69     for(int i=1;i<=n;i++) ins();
    70     build();
    71     dfs(0);
    72     if(f_ring()) puts("TAK");
    73     else puts("NIE");
    74     return 0;
    75 }
  • 相关阅读:
    c coroutine
    leveldb(ssdb)性能、使用场景评估
    [微信协议分析] 多媒体
    [微信协议分析] 多点登陆
    [微信协议分析] 文本消息
    paxos(chubby) vs zab(Zookeeper)
    分布式一致性算法
    erlang 健壮性
    tcp 出现rst情况整理
    tcp_tw_reuse、tcp_tw_recycle 使用场景及注意事项
  • 原文地址:https://www.cnblogs.com/J-william/p/7354586.html
Copyright © 2011-2022 走看看