003:躲不開的病毒

總時間限制: 1000ms 內存限制: 1000kB
描述
有若干種病毒,每種病毒的特徵代碼都是一個01串。

每個程序也都是一個01串。

問是否存在不被病毒感染(不包含任何病毒的特徵代碼)的無限長的程序。

輸入
第一行是整數n,表示有n個病毒
接下來n行,每行是一個由 0,1構成的字符串,表示一個病毒特徵代碼
所有的病毒的特徵代碼總長度不超過30000
輸出
如果存在無限長的沒有被病毒感染的程序,輸出 “TAK”,否則輸出"NIE"
樣例輸入
樣例1:
2
10
11
樣例2:
2
1
0
樣例輸出
樣例1:
TAK
樣例2:
NIE

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
struct NODE
{
    bool end;
    bool visit;
    NODE *pre;
    NODE *child[2];
    NODE()
    {
        end = false;
        visit = false;
        pre = NULL;
        child[0] = NULL;
        child[1] = NULL;
    }
} tree[30005];
char s[30001];
int cnt = 1;
void insert(NODE*root)
{
    for (int i = 0; s[i]; i++)
    {
        int temp = s[i] - '0';
        if(root->child[temp] == NULL)
        {
            cnt++;
            root->child[temp] = tree + cnt;
        }
        root = root->child[temp];
    }
    root->end = true;
}
queue<NODE*> q;
void buildpre()
{
    tree[0].child[0] = tree + 1;
    tree[0].child[1] = tree + 1;
    tree[1].pre = tree;
    q.push(tree+1);
    while(!q.empty())
    {
        NODE *temp = q.front();
        q.pop();
        for (int i = 0; i < 2; i++)
        {
            NODE *p = temp->child[i];
            if(p)
            {
                NODE *mypre = temp->pre;
                while(mypre->child[i] == NULL)
                {
                    mypre = mypre->pre;
                }
                p->pre = mypre->child[i];
                if(p->pre->end)
                {
                    p->end = true;
                }
                q.push(p);
            }
        }
    }
}
int flag = 0;
bool travel(NODE *root, bool ans)
{
    if (ans || flag)
    {
        flag = 1;
        return true;
    }
    if (root->end)
    {
        
        return false;
    }
    if(root->visit)
    {
        flag = 1;
        return true;
    }
    root->visit = true;
    bool ss[2] = {0, 0};
    for (int i = 0; i < 2; i++)
    {
        if(root->child[i])
        {
            ss[i] = travel(root->child[i], false);
        }
        else 
        {
            NODE *m = root->pre;
            while(m->child[i] == NULL)
            {
                m = m->pre;
            }
            ss[i] = travel(m->child[i], false);
        }
    }
    root->visit = false;
    ans = ss[0] || ss[1];
    return ans;
}
int main()
{
   // freopen("myin.txt", "r", stdin);
   // freopen("myout.txt", "w", stdout);
    int n;
    cin >> n;
    while(n--)
    {
        memset(s, 0, sizeof(s));
        cin >> s;
        insert(tree + 1);
    }
    buildpre();
    bool ans = travel(tree + 1, false);
    if(ans)
    {
        cout << "TAK";
    }
    else
    {
        cout << "NIE";
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章