日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ2938:[POI2000] 病毒

發布時間:2025/10/17 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ2938:[POI2000] 病毒 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

二進制病毒審查委員會最近發現了如下的規律:某些確定的二進制串是病毒的代碼。如果某段代碼中不存在任何一段病毒代碼,那么我們就稱這段代碼是安全的。現在委員會已經找出了所有的病毒代碼段,試問,是否存在一個無限長的安全的二進制代碼。 示例: 例如如果{011, 11, 00000}為病毒代碼段,那么一個可能的無限長安全代碼就是010101…。如果{01, 11, 000000}為病毒代碼段,那么就不存在一個無限長的安全代碼。 任務: 請寫一個程序: l???????? 讀入病毒代碼; l???????? 判斷是否存在一個無限長的安全代碼; l???????? 將結果輸出

Input

第一行包括一個整數n,表示病毒代碼段的數目。以下的n行每一行都包括一個非空的01字符串——就是一個病毒代碼段。所有病毒代碼段的總長度不超過30000。

Output

你應在在文本文件WIN.OUT的第一行輸出一個單詞: l???????? TAK——假如存在這樣的代碼; l???????? NIE——如果不存在。

Sample Input

3
01
11
00000

Sample Output

NIE 思路: 首先將所有病毒串建一棵AC自動機。 想象一個無限長的安全代碼存在,那么拿它到AC自動機上匹配,它會一直匹配但是一直匹配不成功。 也就是說匹配的時候不能匹配到End為1的結點(設為x),且fail指針指向終點的點(設為y)也不能匹配到,因為root..x是root..y的一個后綴。 而要無限長,即一直匹配,就說明在匹配過程中會遇上一個環。 所以就是在AC自動機上看有沒有環就行了。

感覺每做一道AC自動機的題就重新學一遍AC自動機

#include <bits/stdc++.h> #define ll long long using namespace std; const int p=10007; const int N=1e6+10; const int M=5e5+10; int n,T; char s[N]; struct acmach {int Next[M][2],Fail[M];bool End[M];bool vis[N],in[N];int root,L;int newnode(){for (int i=0;i<2;i++) Next[L][i]=-1;End[L]=0;return L++;}void init(){L=0;root=newnode();for (int i=0;i<N;i++) vis[i]=in[i]=0;}void Insert(char s[]){int len=strlen(s);int now=root;for (int i=0;i<len;i++){if (Next[now][s[i]-'0']==-1)Next[now][s[i]-'0']=newnode();now=Next[now][s[i]-'0'];}End[now]=1;}void build(){queue<int>q;Fail[root]=root; for (int i=0;i<2;i++)if (Next[root][i]==-1) Next[root][i]=root; else{Fail[Next[root][i]]=root;q.push(Next[root][i]);}while (!q.empty()){int now=q.front(); q.pop();End[now]|=End[Fail[now]]; //對于File指向End的點也不能訪問到for (int i=0;i<2;i++)if (Next[now][i]==-1) Next[now][i]=Next[Fail[now]][i]; else{Fail[Next[now][i]]=Next[Fail[now]][i]; q.push(Next[now][i]);}}}bool dfs(int x){in[x]=1;for (int i=0;i<2;i++){int v=Next[x][i];if (in[v]) return 1;if (vis[v] || End[v]) continue;vis[v]=1;if (dfs(v)) return 1;}in[x]=0;return 0;} }ac; int main() {ac.init();scanf("%d",&n);for (int i=1;i<=n;i++){scanf("%s",s);ac.Insert(s);}ac.build();if (ac.dfs(ac.root)) printf("TAK\n");else printf("NIE\n");return 0; } View Code

轉載于:https://www.cnblogs.com/tetew/p/11545214.html

總結

以上是生活随笔為你收集整理的BZOJ2938:[POI2000] 病毒的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。