总时间限制: 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;
}