当前位置: 首页 > news >正文

P2536 [AHOI2005] 病毒检测

P2536 [AHOI2005] 病毒检测

题目描述

科学家们在 Samuel 星球上的探险仍在继续。非常幸运的,在 Samuel 星球的南极附近,探险机器人发现了一个巨大的冰湖!机器人在这个冰湖中搜集到了许多 DNA 片段运回了实验基地。

科学家们经过几个昼夜的研究,发现这些 DNA 片段中有许多是未知的病毒!

每个 DNA 片段都是由 ACTG 组成的序列。科学家们也总结出了 Samuel 星球上的“病毒模版片段”。一个模版片段是由 ACTG 的序列加上通配符 *? 来表示。其中 * 的意思是可以匹配上 000 个或任意多个字符,而 ? 的意思是匹配上任意一个字母。

如果一个 DNA 片段能够和“病毒模版片段”相匹配,那么这个 DNA 片段就是未知的病毒。

例如,假设 “病毒模版片段”为 A*G?C。DNA 片段:AGTCAGTGTC 都是未知的病毒,而 DNA 片段 AGTGC 则不是病毒。

由于,机器人搜集的这些 DNA 片段中除去病毒的其他部分都具有非常高的研究价值。所以科学家们希望能够分辨出其中哪些 DNA 片段不是病毒,并将不是病毒的 DNA 片段运回宇宙空间站继续进行研究。

科学家将这项任务交给了小联。现在请你为小联编写程序统计哪些 DNA 片段不是病毒。

输入格式

N+2N+2N+2 行输入。

第一行有一个字符串,由 ACTG*? 组成,表示“病毒模版片段”。“病毒模版片段”的长度不超过 100010001000

第二行有一个整数 NNN,表示机器人搜集到的 DNA 片段的数目。

随后的 NNN 行,每一行有一个字符串,由 ACTG 组成,表示一个 DNA 片段。

输出格式

只有一行输出,为整数 MMM,即不是病毒的 DNA 片段的数目。

输入输出样例 #1

输入 #1

A*G?C
3
AGTC
AGTGTC
AGTGC

输出 #1

1

说明/提示

输入中的 DNA 片段 AGTGC 不是病毒。

对于所有数据,0<N<5000 < N < 5000<N<500

特别的:

  • 每个 DNA 片段的长度不超过 500500500
  • “病毒模版片段”和 DNA 片段的长度都至少为 111

解析

本题基本可以看成一个病毒标准串与多个DNADNADNA模式串的匹配。
当想到是多个字符串与单个字符串匹配时,我们可以想到 Trie树Trie树Trie
(Trie树Trie树Trie不在此详细介绍)

然而难度在于,标准串的形式不唯一,复杂多变不可定。那么我们思考,能否在由多个DNADNADNA模式串形成的Trie树Trie树Trie上搜索符合标准串格式的串,并统计个数。

那么这里使用深搜(dfsdfsdfs),将标准串遍历一遍来实现搜索。

I考虑搜索的策略:

假设当前扫到了标准串 vvv 的某一位 vpv_pvp
注:树上点的对应子节点是指:表示的字母 与 接下来搜索的标准串的字母相同 的子节点

①若 vpv_pvp 是字母,则直接搜索下一位 vp+1v_{p+1}vp+1,树上搜索的位置也来到对应的子节点(若没有对应子节点的话将不会进行搜索)。因为此时你根本没有任何其他搜索的选择。

②若 vpv_pvp是问号(???),此时我们拥有 444 个搜索的方向(A、T、C、GA、T、C、GATCG),对于此我们把树上搜索的位置分别移到 444 个子节点,再分别搜索接下来的 vp+1v_{p+1}vp+1,进行进一步深搜。

③若 vpv_pvp 是星号(∗*),其难度在于它可代替任意长度的字符串。但是想到,问号可以取代一位,那么“∗”“*”就是若干个“?”“?”?,对此我们每次搜索时,分别搜索 444 个子节点,而 ppp 的情况有两种:要么移到 vp+1v_{p+1}vp+1(相当于“∗”“*”取代字母到此为止了),要么保持 vpv_{p}vp(相当于下一位还是由“∗”“*”取代产生的)。不必担心“?”“?”?取代的搜索会无穷尽,因为Trie树Trie树Trie是有限的,导致串无法无限的搜索。
当然别忘了“?”“?”?还能表示没有字母,所以直接搜索 vp+1v_{p+1}vp+1 且不考虑移动树上的搜索点即可。

而终止条件就是 p=len(v)p=len(v)p=len(v) 的时候,此时标准串已经被扫完,只需记录此时以当前树上搜索点结尾的模式串有几个即可。

当然,面对拗口的解释并不足以理解,但在代码中将会有详细注释更加强理解

II考虑优化

显然在深搜时会出现相同状态的重复搜索,进而导致超时。解决这种问题的最佳方法就是记忆化搜索记录已经搜过的状态,再次遇到时就不必继续重复的搜索。

III代码及注释

#include<bits/stdc++.h>
using namespace std;
int n;
char dis[4]={'A','C','T','G'};
string v;
string s;
int trie[250010][40];
bool vis[1000][250010];
int tot;
void append(){//建Trie树的基本过程不再赘述int p=0;int len=s.length();for(int i=0;i<len;i++){if(!trie[p][s[i]-'A']){tot++;trie[p][s[i]-'A']=tot;}p=trie[p][s[i]-'A'];}trie[p][29]++;//记录以该节点结尾的模式串个数
}
int ans;
int l; //v的长度
void dfs(int p,int t){//p为模式串匹配到的位置 [0,l),t为trie树的点位 if(p==l){//匹配完了ans+=trie[t][29];trie[t][29]=0;//清零以避免重复加。//因为一个模式串可能有多种方法匹配。return;}if(vis[p][t]) return;//搜过了这种状态不搜了vis[p][t]=true;//标记该状态已搜if('A'<=v[p]&&v[p]<='Z'&&trie[t][v[p]-'A']){//v[p]是字母且该节点有对应儿子dfs(p+1,trie[t][v[p]-'A']);}else if(v[p]=='?'){//v[p]是"?"时有四种选择for(int i=0;i<=3;i++){if(trie[t][dis[i]-'A']){dfs(p+1,trie[t][dis[i]-'A']);}}}else if(v[p]=='*'){dfs(p+1,t);//"*"表示没有字母for(int i=0;i<=3;i++){if(trie[t][dis[i]-'A']){dfs(p+1,trie[t][dis[i]-'A']);//"*"代替完了dfs(p,trie[t][dis[i]-'A']);//"*"继续代替若干个字母}}}
}
int main(){cin>>v>>n;for(int i=1;i<=n;i++){cin>>s;append();}l=v.length();dfs(0,0);cout<<n-ans;//ans是匹配得上的个数,而题目求匹配不上的个数return 0;
}

IV其他的方法

据同机房的大佬LEE表示,,存在一种将 vvv 所有情况建成有自环的 Trie树Trie树Trie。但本蒟蒻还不明白……

谢谢阅读,能给个赞吗?

http://www.dtcms.com/a/429589.html

相关文章:

  • 建设部网站内装修标准seo推广内容
  • 网站读取错误时怎样做做网站常用的套件
  • 张家港手机网站设计旧房改造找哪家
  • 用wordpress做商城seo优化方案设计
  • wordpress 产品库seo的定义
  • 海口百度seo公司商丘seo公司找25火星
  • 做黑网站赚钱技巧建设银行网站不能登录不了
  • 北京市建筑网站申请企业资助建设网站
  • 做网站jsp和php厦门住房建设局网站
  • wordpress 搭建交易所单页式网站 seo
  • 再谈电子实验记录本的部署方式——本地私有、云私有、单租户及多租户SaaS
  • 闸北区网站制作怎么查网站的浏览量
  • 免费做网站公司聚美优品的pc网站建设
  • 【初学】调试 MCP Server
  • 基层建设期刊在哪个网站被收录一家做土产网站
  • 沙河企业做网站vps网站设置
  • 樱花动漫做网站专业网站建设人工智能研发
  • Your Man - Josh Turner
  • 自适应企业网站源码做视频网站适合用什么服务器
  • 网站设计与建设word设计理念滨海哪家专业做网站
  • 做网站材料网站模块在线制作教程
  • 犀牛云网站建设公司深圳专业建站平台
  • 手机网站 像素wordpress free theme
  • 企业网站建设论坛宁夏水利厅建设管理处网站
  • 自助商城网站建设如何做网站链接
  • 做网站下一页设计公司画册设计
  • wordpress 自助建站西安建网站价格
  • 行业类网站模板网站开发工程师社交
  • 营销型网站建设申请域名时公司类型的域名后缀一般是老总办公室装修风格
  • 外贸公司建网站一般多少钱编辑制作网页的基础是