• [POI2000]病毒


              [POI2000]病毒

    题目描述

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

    示例:

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

    任务:

    请写一个程序:

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

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

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

    输入输出格式

    输入格式:

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

    输出格式:

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

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

    NIE——如果不存在。

    输入输出样例

    输入样例#1:
    3
    01 
    11 
    00000
    
    输出样例#1:
    NIE

    根据给出的病毒建出AC自动机,在上面DFS找环,单词的结尾的节点不能走,有环就代表有解。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <queue>
      5 #include <algorithm>
      6 #define LL long long
      7 
      8 using namespace std;
      9 
     10 queue<int> q;
     11 int len;
     12 const int MAXN = 2e3 + 10;
     13 char s[MAXN];
     14 int vis[MAXN], instack[MAXN];
     15 int flag = 0;
     16 struct trie {
     17     int fail;
     18     int vis[2];
     19     int judge;
     20 } t[MAXN * 10];
     21 
     22 inline LL read()
     23 {
     24     LL x = 0, w = 1; char ch = 0;
     25     while(ch < '0' || ch > '9') {
     26         if(ch == '-') {
     27             w = -1;
     28         }
     29         ch = getchar();
     30     }
     31     while(ch >= '0' && ch <= '9') {
     32         x = x * 10 + ch - '0';
     33         ch = getchar();    
     34     }
     35     return x * w;
     36 }
     37 int tot = 0;
     38 
     39 void insert()
     40 {
     41     int x = 0;
     42     for(int i = 1; i <= len; i++) {
     43         if(t[x].vis[s[i] - '0'] == 0) {
     44             t[x].vis[s[i] - '0'] = ++tot;
     45         }
     46         x = t[x].vis[s[i] - '0'];
     47     }
     48     t[x].judge = 1;
     49 }
     50 
     51 void getfail()
     52 {
     53     for(int i = 0; i < 2; i++) {
     54         if(t[0].vis[i]) {
     55             t[t[0].vis[i]].fail = 0;
     56             q.push(t[0].vis[i]);        
     57         }
     58     }
     59     while(!q.empty()) {
     60         int x = q.front();
     61         q.pop();
     62         for(int i = 0; i < 2; i++) {
     63             if(!t[x].vis[i]) {
     64                 t[x].vis[i] = t[t[x].fail].vis[i];
     65             } else { 
     66                 t[t[x].vis[i]].fail = t[t[x].fail].vis[i];
     67                 if(t[t[t[x].vis[i]].fail].judge == 1) {
     68                     t[t[x].vis[i]].judge = 1;
     69                 }
     70                 q.push(t[x].vis[i]);
     71             }
     72         }
     73     }
     74 }
     75 
     76 void DFS(int x)
     77 {
     78     instack[x]++;
     79     if(flag || t[x].judge == 1) {
     80         return;
     81     }
     82     vis[x] = 1;
     83     for(int i = 0; i < 2; i++) {
     84         if(vis[t[x].vis[i]] == 1 && instack[t[x].vis[i]]) {
     85             //cout<<t[x].vis[i]<<endl;
     86             flag = 1;
     87             return;
     88         }
     89         if(!vis[t[x].vis[i]]) {
     90             DFS(t[x].vis[i]);
     91         }
     92     }
     93     instack[x]--;
     94 }
     95 
     96 int main()
     97 {
     98     int n;
     99     n = read();
    100     for(int i = 1; i <= n; i++) {
    101         scanf("%s", s + 1);
    102         len = strlen(s + 1);
    103         insert();
    104     }
    105     getfail();
    106     flag = 0;
    107     DFS(0);
    108     if(flag) {
    109         cout<<"TAK"<<endl;
    110     } else {
    111         cout<<"NIE"<<endl;
    112     }
    113 }
    114  
    View Code
  • 相关阅读:
    7z usecaes
    最新状态
    ABAP 常用FUNCTION (最近工作中用到的)
    又是一个星期五
    阿牛
    自我定位的重要性
    smortform 创建
    换个角度想或许不一样
    为什么喜欢跟男生聊天小小分析
    BDC 代码设置
  • 原文地址:https://www.cnblogs.com/wuenze/p/8659704.html
Copyright © 2020-2023  润新知