列表

详情


NC50358. 病毒

描述

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

输入描述

第一行包括一个整数n,表示病毒代码段的数目;
以下的n行,每一行都包括一个非空的01字符串——就是一个病毒代码段。

输出描述

第一行输出一个单词。假如存在这样的代码,则输出TAK,否则输出NIE。

示例1

输入:

3
01 
11 
00000

输出:

NIE

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 4ms, 内存消耗: 716K, 提交时间: 2022-09-17 23:10:08

#include<bits/stdc++.h>
using namespace std;
const int N = 3e4+10;
int tr[N][2],st[N],idx;
int q[N],fail[N];
int n;
char s[N];
int vs[N];
void insert()
{
    int u=0;
    for(int i=0;s[i];i++)
    {
        int t=s[i]-'0';
        if(!tr[u][t])tr[u][t]=++idx;
        u=tr[u][t];
    }
    st[u]=1;
}
void build()
{
    int hh=0,tt=0;
    for(int i=0;i<2;i++)
        if(tr[0][i])q[tt++]=tr[0][i];
    while(hh!=tt)
    {
        int t=q[hh++];
        for(int i=0;i<2;i++)
        {
            int u=tr[t][i];
            if(!u)tr[t][i]=tr[fail[t]][i];
            else
            {
                fail[u]=tr[fail[t]][i];
                q[tt++]=u;
                st[u]|=st[fail[u]];
            }
        }
    }
}
bool dfs(int u)
{
    if(vs[u]==1)return true;
    else if(vs[u]==-1)return false;

    vs[u]=1;
    for(int i=0;i<2;i++)
    {
        if(!st[tr[u][i]]&&dfs(tr[u][i]))return true;
    }
    vs[u]=-1;
    return false;
}

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>s;
        insert();
    }
    build();
    if(dfs(0))puts("TAK");
    else puts("NIE");
    return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 4ms, 内存消耗: 784K, 提交时间: 2023-05-13 20:18:43

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int n,m,t[N][2],cnt,ne[N],tag[N],tot,tt[N],v[N],vv[N];
string s;
void add(){
	int p=0,len=s.size();
	for(int i=0;i<len;i++){
		int j=s[i]-'0';
		if(!t[p][j])t[p][j]=++cnt;
		p=t[p][j];
	}
	tag[p]=1;
}
void kmp(){
	queue<int>q;
	for(int i=0;i<2;i++)if(t[0][i])q.push(t[0][i]);
	while(!q.empty()){
		int p=q.front();
		q.pop();
		tt[++tot]=p;//拓扑序 
		for(int i=0;i<2;i++){
			int j=t[p][i],v=t[ne[p]][i];
			if(j){
				ne[j]=v;
				q.push(j);
				tag[j]|=tag[v];
			}
			else t[p][i]=v;
		}
	}
}
void dfs(int x){
	if(v[x]){
		cout<<"TAK";
		exit(0);
	}
	if(vv[x])return;
	v[x]=1;
	vv[x]=1;
	if(!tag[t[x][0]])dfs(t[x][0]);
	if(!tag[t[x][1]])dfs(t[x][1]);
	v[x]=0;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>s;
		add();
	}
	kmp();
	dfs(0);
	cout<<"NIE";
}

上一题