Luogu P2536 [AHOI2005]病毒检测
题意
给一个有通配符的模式串和 \(n\) 个文本串,其中 ? 可以匹配任意字符,* 可以匹配 \(0\) 或任意多个字符,求 \(n\) 个文本串中无法与模式串匹配的数量。
\(\texttt{Data Range:}1\leq n\leq 500\)
题解
非确定性有限状态决策自动机。
首先考虑对模式串建一个自动机。对于每一位我们可以抽象成一个节点,整个字符串可以抽象成一个转移图。在匹配的过程中,如果能够走到这个节点上来就说明能够与这个位置的前缀相匹配。这里需要讨论一下:
如果模式串的某一位为字母,那么将这一位的状态向下一位的状态连这个字母的边,也就是说只有这个字母能从这一位转移到下一位。
如果模式串的某一位为
?,那么任何字母进来都能匹配上,也就是说将这一位的状态向下一位的状态连所有字母的边。如果模式串的某一位为
*,这里是个小 trick,也就是说可以匹配任意长度的串,那就连个自环就可以了。
然后,对于匹配的话,从初始状态开始走,如果能够走到结束状态那么则匹配成功。
代码非常好写,跑得也很快。
代码
#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=1e3+51;
struct Node{
ll isEnd;
vector<ll>nxt[4];
};
Node x[MAXN];
vector<ll>s,nxt;
ll n,len,tot,c,flg,res;
ll mp[128],vis[MAXN];
char ch[MAXN];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
inline void match()
{
s.clear(),s.push_back(1);
for(register int i=1;i<=len;i++)
{
nxt.clear(),flg=0;
for(register int j=1;j<=tot;j++)
{
vis[j]=0;
}
for(register int j=0;j<s.size();j++)
{
for(register int k=0;k<x[s[j]].nxt[mp[ch[i]]].size();k++)
{
if((c=x[s[j]].nxt[mp[ch[i]]][k])&&!vis[c])
{
vis[c]=1,nxt.push_back(c),flg|=x[c].isEnd;
}
}
}
s=nxt;
}
res+=1-flg;
}
int main()
{
scanf("%s",ch+1),len=strlen(ch+1),tot=1,memset(mp,-1,sizeof(mp));
mp['A']=0,mp['G']=1,mp['C']=2,mp['T']=3;
for(register int i=1;i<=len;i++)
{
if(mp[ch[i]]!=-1)
{
x[tot].nxt[mp[ch[i]]].push_back(tot+1),tot++;
continue;
}
if(ch[i]=='?')
{
x[tot].nxt[0].push_back(tot+1),x[tot].nxt[1].push_back(tot+1);
x[tot].nxt[2].push_back(tot+1),x[tot].nxt[3].push_back(tot+1);
tot++;
continue;
}
if(ch[i]=='*')
{
x[tot].nxt[0].push_back(tot),x[tot].nxt[1].push_back(tot);
x[tot].nxt[2].push_back(tot),x[tot].nxt[3].push_back(tot);
continue;
}
}
x[tot].isEnd=1,n=read();
for(register int i=0;i<n;i++)
{
scanf("%s",ch+1),len=strlen(ch+1),match();
}
printf("%d\n",res);
}
Luogu P2536 [AHOI2005]病毒检测的更多相关文章
- P2536 [AHOI2005]病毒检测
反思 对于*符号,明明可以让相同位置再次匹配下一个,或者跳过当前位置匹配,但是却写了个把trie的子树全部push进队列的垃圾写法,结果一直MLE 告辞 思路 模板串多且不长,可以塞到trie树里,这 ...
- 【BZOJ1966】[AHOI2005]病毒检测(动态规划)
[BZOJ1966][AHOI2005]病毒检测(动态规划) 题面 BZOJ 洛谷 题解 我就蒯了一份代码随便改了改怎么就过了??? 从这道题目蒯的 代码: #include<iostream& ...
- [AHOI2005]病毒检测
Description 科学家们在Samuel星球上的探险仍在继续.非常幸运的,在Samuel星球的南极附近,探险机器人发现了一个巨大的冰湖!机器人在这个冰湖中搜集到了许多RNA片段运回了实验基地.科 ...
- 【[AHOI2005]病毒检测】
\(Trie\) 树+搜索 我用的是\(dfs\) 首先对于将所有的RNA片段都建到\(Trie\)树里去,之后来匹配那个模板串就好了 如果是匹配的位置是字母,那么我们就继续往下匹配 如果是\(?\) ...
- bzoj1966:[AHOI2005]病毒检测
传送门 我也没想到map如此垃圾,bitset优秀啊 直接trie树上搜索就好了 代码: #include<cstdio> #include<iostream> #includ ...
- [luogu P2054] [AHOI2005]洗牌
[luogu P2054] [AHOI2005]洗牌 题目描述 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动. 由于Samuel星球相当遥远,科学 ...
- 基于深度学习的病毒检测技术无需沙箱环境,直接将样本文件转换为二维图片,进而应用改造后的卷积神经网络 Inception V4 进行训练和检测
话题 3: 基于深度学习的二进制恶意样本检测 分享主题:全球正在经历一场由科技驱动的数字化转型,传统技术已经不能适应病毒数量飞速增长的发展态势.而基于沙箱的检测方案无法满足 APT 攻击的检测需求,也 ...
- 【Luogu】P2536病毒检测(Trie上DP)
题目链接 这道题我写了个01DP,f[i][j]表示跑到Trie上第i个节点,匹配到字符串第j位行不行 然后重点在*号无限匹配怎么处理 经过一番脑洞我们可以发现*号无限匹配可以拆成两种情况: 1:匹配 ...
- bzoj1966: [Ahoi2005]VIRUS 病毒检测
Description 科学家们在Samuel星球上的探险仍在继续.非常幸运的,在Samuel星球的南极附近,探险机器人发现了一个巨大的冰湖!机器人在这个冰湖中搜集到了许多RNA片段运回了实验基地.科 ...
随机推荐
- Oracle12c 使用总结
/*创建临时表空间 */create temporary tablespace BBB tempfile 'D:\APP\oracle\oradata\orcl\BBB.dbf' size 500m ...
- spring-boot-route(一)Controller接收参数的几种方式
Controller接收参数的常用方式总体可以分为三类.第一类是Get请求通过拼接url进行传递,第二类是Post请求通过请求体进行传递,第三类是通过请求头部进行参数传递. 1 @PathVariab ...
- 基于springboot工程浅谈整合rabbitmq怎么样防止消息发送mq不丢失和消费mq的消息防止丢失
本文只针对springboot整合rabbitmq的消息防丢失,话不多说,上干货.... 设置发送mq消息不丢失实现思路 执行的方案: 第一步,要对队列,消息以及交换机进行持久化操作(保存到物理磁盘中 ...
- C++枚举变量与switch
转载:https://www.cnblogs.com/banmei-brandy/p/11263927.html 枚举类型和变量如何定义,下篇博客讲得十分详细: https://blog.csdn.n ...
- JavaCV FFmpeg采集摄像头YUV数据
前阵子使用利用树莓派搭建了一个视频监控平台(传送门),不过使用的是JavaCV封装好的OpenCVFrameGrabber和FFmpegFrameRecorder. 其实在javacpp项目集中有提供 ...
- phpstorm中配置使用svn详细步骤
一.搭建SVN环境 1.下载VisualSVN Sever.下载地址:https://www.visualsvn.com/server/download/ 2.安装VisualSVN Server. ...
- 开始接触flex
flex框架使用的是.mxml后缀的文件,可以在Eclipse导入flex开发的插件.代码写完之后需要进行编译成为.swf文件成功之后才可以正常运行.现在刚开始接触金融的项目,需求什么的还有很多不是理 ...
- AMBuild
什么是AMBuild? AMBuild是构建软件项目和创建发布包的工具.它是针对C++项目的,当然也可以用于其它任何语言的项目,它主要针对解决大多数构建工具所解决不了的三个大问题: 1.准确性:不需要 ...
- <二分查找+双指针+前缀和>解决子数组和排序后的区间和
<二分查找+双指针+前缀和>解决子数组和排序后的区间和 题目重现: 给你一个数组 nums ,它包含 n 个正整数.你需要计算所有非空连续子数组的和,并将它们按升序排序,得到一个新的包含 ...
- 【C语言学习笔记系列】C语言编程狼追兔子问题代码解析!
问题描述 一只兔子躲进了10个环形分布的洞中的一个.狼在第一个洞中没有找到兔子,就隔一个洞,到第3个洞去找:也没有找到,就隔2个洞,到第6个洞去找:以后每次多一个洞去找兔子--这样下去,如果一直找不到 ...