P2536 [AHOI2005]病毒检测(记忆化搜索)

题目描述

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

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

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

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

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

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

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

输入输出格式

输入格式:

第一行有一个字符串,由A、C、T、G、*、? 组成。表示“病毒模版片段”。“病毒模版片段”的长度不超过1000。第二行有一个整数N(0<N<500),表示机器人搜集到的RNA片段的数目。随后的N行,每一行有一个字符串,由A、C、T、G组成,表示一个RNA片段。每个RNA片段的长度不超过500。注意:“病毒模版片段”和RNA片段的长度都至少为1。

输出格式:

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

输入输出样例

输入样例#1: 复制
A*G?C
    3
AGTC
AGTGTC
AGTGC
输出样例#1: 复制
1

说明

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




在做这个提之前,你要知道一个事情,就是rna必须从头开始匹配 。。。。。。

然而开始不知道这个,在想题解为什么不建fail  qwq

 

模板到了*,模板走串不走 或者 模板不走串走

模板到了agut ,能匹配就走

模板到了? ,都走一步

vis[x][y] 表示模板到了第x位,到了树上的y节点,记忆一波

唯有吸氧才能救这个码 嘿嘿




 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<bitset>
5 #include<queue> 6 using namespace std; 7 const int N=500+5; 8 const int L=1000+5; 9 const int M=N*N; 10 template<class T>inline void read(T &num){ 11 char ch; 12 while(!isdigit(ch=getchar())); 13 num=ch-'0'; 14 while(isdigit(ch=getchar()))num=num*10+ch-'0'; 15 } 16 17 int mmp[300];//愤怒之情溢于数组 18 int tri[M][4],is_end[M],fla[M],totn=1,n,ans,res[M],valu[L]; 19 char str[L],s[N]; 20 inline void Insert(char s[]){ 21 int len=strlen(s),x=0; 22 for(int p=0;p<len;++p){ 23 int ch=mmp[s[p]]; 24 if(tri[x][ch]==0){ 25 tri[x][ch]=++totn; 26 } 27 x=tri[x][ch]; 28 } 29 is_end[x]++; 30 } 31 32 struct Data{ 33 int first,second; 34 Data(const int a=0,const int b=0){ 35 first=a,second=b; 36 } 37 }; 38 39 queue<Data>que; 40 bitset<L> vis[M]; 41 inline void Push(const int x,const int y){ 42 if(vis[x][y])return; 43 que.push(Data(x,y)); 44 vis[x][y]=true; 45 } 46 47 inline void bfs(){ 48 int len=strlen(str),x,p; 49 Push(0,0); 50 while(que.size()){ 51 x=que.front().first,p=que.front().second;que.pop(); 52 if(p==len){ 53 if(fla[x]==0){ 54 ans-=is_end[x]; 55 fla[x]=1; 56 } 57 continue; 58 } 59 int ch=mmp[str[p]]; 60 if(ch<4&&tri[x][ch])Push(tri[x][ch],p+1); 61 else if(ch==4){ 62 Push(x,p+1); 63 for(int i=0;i<4;++i)if(tri[x][i])Push(tri[x][i],p); 64 } 65 else if(ch==5)for(int i=0;i<4;++i)if(tri[x][i])Push(tri[x][i],p+1); 66 } 67 } 68 69 int main(){ 70 mmp['G']=1,mmp['C']=2,mmp['T']=3,mmp['*']=4,mmp['?']=5; 71 scanf("%s",str); 72 read(n); 73 ans=n; 74 for(int i=1;i<=n;++i){ 75 scanf("%s",s); 76 Insert(s); 77 } 78 bfs(); 79 printf("%d\n",ans); 80 return 0; 81 }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

上一篇:反射型XSS <?php echo $_GET[‘x‘];?> 笔记


下一篇:宁哥科普:新型冠状病毒能被杀死吗?