分析
要求有一条可以无限长的串,满足所有字串没有出现过。那么我们可以考虑 自动机。我们用
表示,那个无限长的串不可以匹配的节点。那么我们就会有这个转移
,因为
是我的一个后缀,那么后缀都不能到,更别说自己了。那么我们直接在
自动机上
就好了。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 3e4 + 100;
int ch[N][2],fail[N],size,inq[N];
char S[N];
int n,vis[N];
void ins(char *s) {
int len = strlen(s + 1);int u = 0;
for(int i = 1;i <= len;i++) {
int c = s[i] - '0';
if(!ch[u][c]) ch[u][c] = ++size;
u = ch[u][c];
// cout << u << endl;
}
vis[u] |= 1;
}
void build() {
queue<int> Q;
for(int i = 0;i < 2;i++) if(ch[0][i]) Q.push(ch[0][i]);
while(!Q.empty()) {
int u = Q.front();Q.pop();
for(int i = 0;i < 2;i++) {
if(ch[u][i]) {
fail[ch[u][i]] = ch[fail[u]][i];
vis[ch[u][i]] |= vis[ch[fail[u]][i]];
Q.push(ch[u][i]);
}
else ch[u][i] = ch[fail[u]][i];
}
}
}
bool dfs(int x) {
// cout << x << endl;
if(inq[x] == 1) return true;
if(inq[x] == -1) return false;
inq[x] = 1;
bool res = 0;
for(int i = 0;i < 2;i++) {
if(!vis[ch[x][i]]) res |= dfs(ch[x][i]);
if(res) return 1;
}
inq[x] = -1;
return false;
}
int main() {
scanf("%d",&n);
for (int i = 0;i < n;++i) {
scanf("%s",S + 1);ins(S);
}
build();
if(!dfs(0)) cout << "NIE" << endl;
else cout << "TAK" << endl;
}
京公网安备 11010502036488号