2938: [Poi2000]病毒
阿新 • • 發佈:2019-01-15
ring lse 無限 urn pac 安全 程序 pre cst
Description
二進制病毒審查委員會最近發現了如下的規律:某些確定的二進制串是病毒的代碼。如果某段代碼中不存在任何一段病毒代碼,那麽我們就稱這段代碼是安全的。現在委員會已經找出了所有的病毒代碼段,試問,是否存在一個無限長的安全的二進制代碼。
示例:
例如如果{011, 11, 00000}為病毒代碼段,那麽一個可能的無限長安全代碼就是010101…。如果{01, 11, 000000}為病毒代碼段,那麽就不存在一個無限長的安全代碼。
任務:
請寫一個程序:
l 讀入病毒代碼;
l 判斷是否存在一個無限長的安全代碼;
l 將結果輸出
只要trie圖上有一個能從0到達且沒有結束標記的環,我們就可以在那個環上繞啊繞啊繞啊
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define M 800001 using namespace std; int n,m,k,cnt,d[M][2],a[M],fail[M],e[M]; char c[M]; bool b[M],bl[M]; queue<int>q; void ins(char* s) { int l=strlen(s), now=0; for(int i=0;i<l;i++) { if(!d[now][s[i]-'0']) d[now][s[i]-'0']=++cnt; now=d[now][s[i]-'0']; } e[now]=1; } void built() { if(d[0][0]) q.push(d[0][0]); if(d[0][1]) q.push(d[0][1]); while(q.size()) { int x=q.front(); q.pop(); if(e[fail[x]]) e[x]=1; if(d[x][0])fail[d[x][0]]=d[fail[x]][0], q.push(d[x][0]); else d[x][0]=d[fail[x]][0]; if(d[x][1]) fail[d[x][1]]=d[fail[x]][1], q.push(d[x][1]); else d[x][1]=d[fail[x]][1]; } } bool bfs(int x) { if(e[x]) return 0; if(bl[x]) return 1; if(b[x]) return 0; bl[x]=b[x]=1; if(bfs(d[x][0])) return 1; if(bfs(d[x][1])) return 1; bl[x]=0; return 0; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",c), ins(c); built(); if(bfs(0)) printf("TAK"); else printf("NIE"); }
2938: [Poi2000]病毒