题目

二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。

示例:

例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。

任务:

请写一个程序:

l 读入病毒代码;

l 判断是否存在一个无限长的安全代码;

l 将结果输出

输入格式

第一行包括一个整数n,表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。

输出格式

你应在在文本文件WIN.OUT的第一行输出一个单词:

l TAK——假如存在这样的代码;

l NIE——如果不存在。

输入样例

3

01

11

00000

输出样例

NIE

题解

我们对所有串建出一个ACM,我们要做的就是在ACM上找一个路径,使得路径包含环且不包含结束节点

对于所有fail指针指向的节点,如果形成串,那么该节点也不能选,因为fail指针指向的为当前串的前缀

建完机后跑一跑dfs检查环就好了

#include<iostream>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 300005,maxm = 1000005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
int ch[maxn][2],siz,fail[maxn],val[maxn];
char s[maxn];
void insert(char* P){
int u = 0,len = strlen(P),x;
for (int i = 0; i < len; i++){
x = P[i] - '0';
if (!ch[u][x]) ch[u][x] = ++siz;
u = ch[u][x];
}
val[u] = 1;
}
void getfail(){
queue<int> q; fail[0] = -1;
for (int i = 0; i < 2; i++) if (ch[0][i]) q.push(ch[0][i]);
int u;
while (!q.empty()){
u = q.front(); q.pop();
for (int i = 0; i < 2; i++){
int v = ch[u][i];
if (!v) {ch[u][i] = ch[fail[u]][i]; continue;}
int k = fail[u];
fail[v] = ch[k][i];
val[v] |= val[ch[k][i]];
q.push(v);
}
}
}
bool flag;
int vis[maxn],ins[maxn];
bool dfs(int u){
ins[u] = true;
for (int i = 0; i < 2; i++){
int v = ch[u][i];
if (ins[v]) return true;
if (vis[v] || val[v]) continue;
vis[v] = true;
if (dfs(v)) return true;
}
ins[u] = false;
return false;
}
int main(){
int n = read();
while (n--) scanf("%s",s),insert(s);
getfail();
dfs(0) ? puts("TAK") : puts("NIE");
return 0;
}

最新文章

  1. Extjs5 tabs实例
  2. Windows 10不能拨L2TP协议的VPN
  3. SHUTDOWN_MSG: Shutting down NameNode at java.net.UnknownHostException: xxx
  4. 黑马程序员----java基础笔记上(毕向东)
  5. Source Tree for MAC1.6
  6. jQuery中prop()函数控制多选框(全选,反选)
  7. javascript中字符串常用操作总结、JS字符串操作大全
  8. leetcode 132. Palindrome Partitioning II ----- java
  9. Java 网络编程(一)
  10. 【转】JavaScript对Json节点的增删改
  11. Android 软件盘 动态设置 layout
  12. HDU5280 Senior&amp;#39;s Array(简单DP)
  13. 关于PC端与手机端随着手指移动图片位置放生变化的拖拽事件
  14. css3整理-方便查询使用
  15. 关于H5从PC端切换到移动端,屏幕显示内容由横向转为竖向的研究!
  16. vue批量验证提交表单的数据是否合规
  17. plsql界面/command界面
  18. MariaDB修改默认字符集
  19. C#读取大数据量Excel
  20. HPU组队赛L(没有标题。。)(贪心)

热门文章

  1. AE开发关于OnMapReplaced方法的使用原理
  2. [神经网络]一步一步使用Mobile-Net完成视觉识别(二)
  3. Jquery二维码在线生成(不能生成图片文件)
  4. 查询linux文件的MD5值
  5. javaweb基础(20)_JavaBean总结
  6. 判断用户ip是否在指定的一个ip段内
  7. d3.js--04(enter和exit)
  8. Unity基础-脚本的基本使用
  9. Python基础——模块与包
  10. python并发编程之线程(创建线程,锁(死锁现象,递归锁),GIL锁)