總時間限制: 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;
}