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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章