zoukankan      html  css  js  c++  java
  • [AHOI2005]病毒检测

    Description
    科学家们在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片段不是病毒。

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

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

    Sample Input

    A*G?C
    3
    AGTC
    AGTGTC
    AGTGC
    

    Sample Output

    1
    

    这题写法其实很暴力……由于数据范围很小,所以我们直接对RNA片段建一棵trie树,然后用模板片段去爆搜,开个bool数组剪枝一下就好了

    然后空间……64MB,MLE(然鹅洛谷可以跑过去)

    所以我们换个想法,考虑dp,设(f[i][j])表示模板匹配到第(i)个位置,RNA片段匹配到第(j)位的情况,如果不是'*'就直接转移一位,否则就用一串转移,单次判断RNA复杂度(O(n^2)),所以总复杂度为(O(n^3))

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int frd(){
    	int x=0,f=1;char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)    putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=5e2;
    bool f[(N<<1)+10][N+10];
    char T[(N<<1)+10];
    int c[(N<<1)+10];
    int main(){
    	scanf("%s",T+1);
    	int lenT=strlen(T+1),Q=read(),Ans=Q;
    	while (Q--){
    		static char s[N+10];
    		memset(f,0,sizeof(f));
    		memset(c,63,sizeof(c));
    		scanf("%s",s+1);
    		int len=strlen(s+1);
    		f[0][0]=1;
    		for (int i=1;i<=lenT;i++){
    			if (T[i]!='*'){
    				for (int j=1;j<=len;j++){
    					if (T[i]=='?'||T[i]==s[j]){
    						f[i][j]|=f[i-1][j-1];
    						if (T[i-1]=='*'&&c[i-1]<j)	f[i][j]=1;
    					}
    				}
    			}else{
    				if (i==1)	f[i][0]=1;
    				for (int j=1;j<=len;j++){
    					f[i][j]|=(f[i-1][j]|f[i][j-1]);
    					if (f[i][j])	c[i]=min(c[i],j);
    				}
    			}
    		}
    		if (f[lenT][len])	Ans--;
    	}
    	printf("%d
    ",Ans);
    	return 0;
    }
    
  • 相关阅读:
    9月16日 星期二 晴
    谁能联系到小爱
    初学者请教Reporting Service达人,小女给能够进来看一眼的好心人抱拳一拜
    9月19日 多云
    iPhone开发教程之Core Data 常见问题的总结
    移动终端开发必备知识
    Core Data 教程(3): 入门指南
    【转载】APK反破解之四:Android代码动态加载技术
    REST是什么
    (转载)设计师必备工具推荐(上)【译】
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/10485571.html
Copyright © 2011-2022 走看看