• 洛谷 P2444 [POI2000]病毒 解题报告


    P2444 [POI2000]病毒

    题目描述

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

    示例:

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

    任务:

    请写一个程序:

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

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

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

    输入输出格式

    输入格式:

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

    输出格式:

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

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

    NIE——如果不存在。


    越想越乱我是得多菜啊

    多串匹配,我们选择AC自动机,要求不能到达单词末尾且无限长度

    等价于在tire图上寻找经过根的环

    (fail)指针的时候可以多把末尾打一些标记以剪枝

    寻找环用tarjan


    Code:

    #include <cstdio>
    #include <cstring>
    const int N=3e5+10;
    int ch[N][2],is[N],fail[N],tot,n,q[N],l,r,ans=1;
    char c[N];
    void init()
    {
        scanf("%s",c+1);
        int len=strlen(c+1),now=0;
        for(int i=1;i<=strlen(c+1);i++)
        {
            if(!ch[now][c[i]-'0']) ch[now][c[i]-'0']=++tot;
            now=ch[now][c[i]-'0'];
        }
        is[now]=1;
    }
    void build()
    {
        if(ch[0][0]) q[r]=ch[0][0];
        if(ch[0][1]) q[++r]=ch[0][1];
        while(l<=r)
        {
            int now=q[l++];
            for(int i=0;i<=1;i++)
            {
                if(ch[now][i])
                {
                    fail[ch[now][i]]=ch[fail[now]][i];
                    is[ch[now][i]]|=is[ch[fail[now]][i]];
                    q[++r]=ch[now][i];
                }
                else ch[now][i]=ch[fail[now]][i];
            }
        }
    }
    int in[N],used[N],flag=0;
    void dfs(int now)
    {
        in[now]=used[now]=1;
        for(int i=0;i<=1;i++)
        {
            int v=ch[now][i];
            if(!used[v]&&!is[v]) dfs(v);
            else if(in[v]) flag=1;
        }
        in[now]=0;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) init();
        build();
        dfs(0);
        if(!flag) printf("NIE
    ");
        else printf("TAK
    ");
        return 0;
    }
    
    

    2018.8.28

  • 相关阅读:
    delphi 文件的读取(二进制文件和文本文件)
    delphi中用代码实现注册Ocx和Dll(有点怪异,使用CallWindowProc来调用指定函数DllRegisterServer)
    delphi 控件大全(确实很全)
    C#编写Windows 服务
    SSD Buffer Pool Extension
    .NET Web开发技术简单整理
    Python数据库访问之SQLite3、Mysql
    infiniband学习总结
    模板引擎开发3自定义标签的处理
    CSS选择器、优先级与匹配原理
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9550588.html
Copyright © 2020-2023  润新知