• [POI2000]病毒


    Description:

    给出n个01串,求是否存在一个无限长度的01串不包含这n个中任意一个串

    Solution:

    若该串合法,则截取其循环的部分,相当于在所有01串中没有匹配,即不经过任一01串的末尾标记
    所以只要在Trie图上找到一个不经过任何病毒串结尾位置的环即可

    #include<bits/stdc++.h>
    using namespace std;
    const int mxn=3e4+5;
    int vis[mxn],ar[mxn];
    char str[mxn],p[7500],ans[5];
    queue<int > q;
    
    namespace Trie {
        int tot,fail[mxn],val[mxn];
        int t[mxn][26];
        void ins(char *s) {
            int len=strlen(s),u=0;
            for(int i=0;i<len;++i) {
                if(!t[u][s[i]-'0']) t[u][s[i]-'0']=++tot;
                u=t[u][s[i]-'0'];
            }
            val[u]=1;
        };
        void build() {
            for(int i=0;i<2;++i) 
                if(t[0][i]) q.push(t[0][i]);
            while(!q.empty()) {
                int u=q.front(); q.pop();
                val[u]|=val[fail[u]];
                for(int i=0;i<2;++i) {
                    if(t[u][i]) fail[t[u][i]]=t[fail[u]][i],q.push(t[u][i]);
                    else t[u][i]=t[fail[u]][i];
                }
            }	
        };
        void dfs(int u) {
            if(vis[u]) {
                puts("TAK");
                exit(0);
            }
            vis[u]=1;
            for(int i=0;i<2;++i) {
                if(!val[t[u][i]]&&ar[t[u][i]]<2) {
                    ar[t[u][i]]++;
                    dfs(t[u][i]);
                }
            }
            vis[u]=0;
        };
    }
    using namespace Trie;
    
    int main()
    {
        int n; scanf("%d",&n);
        for(int i=1;i<=n;++i) 
            scanf("%s",p),ins(p);
        build(); dfs(0); puts("NIE");
        return 0;
    }
    
  • 相关阅读:
    Java8新特性 -- Lambda基础语法
    全角和半角的区别
    java super关键字
    数字格式化
    随机抽奖小程序
    获取指定范围的不重复的随机数
    Java Math类学习
    Java 随机数的产生
    JAVA Color类
    Static和static block(静态块)的用法
  • 原文地址:https://www.cnblogs.com/list1/p/10386281.html
Copyright © 2020-2023  润新知