蓝桥杯 16决赛 C6 碱基(阅读理解)

碱基
生物学家正在对n个物种进行研究。
其中第i个物种的DNA序列为s[i],其中的第j个碱基为s[i][j],碱基一定是A、T、G、C之一。
生物学家想找到这些生物中一部分生物的一些共性,他们现在关注那些至少在m个生物中出现的长度为k的连续碱基序列。准确的说,科学家关心的序列用2m元组(i1,p1,i2,p2…im,pm)表示,
满足:
1<=i1<i2<…<im<=n;
且对于所有q(0<=q<k), s[i1][p1+q]=s[i2][p2+q]=…=s[im][pm+q]。
现在给定所有生物的DNA序列,请告诉科学家有多少的2m元组是需要关注的。如果两个2m元组有任何一个位置不同,则认为是不同的元组。

【输入格式】
输入的第一行包含三个整数n、m、k,两个整数之间用一个空格分隔,意义如题目所述。
接下来n行,每行一个字符串表示一种生物的DNA序列。
DNA序列从1至n编号,每个序列中的碱基从1开始依次编号,不同的生物的DNA序列长度可能不同。
【输出格式】
输出一个整数,表示关注的元组个数。
答案可能很大,你需要输出答案除以1000000007的余数。
【样例输入】
3 2 2
ATC
TCG
ACG
【样例输出】
2
再例如:
【样例输入】
4 3 3
AAA
AAAA
AAA
AAA
【样例输出】
7
【数据规模与约定】
对于20%的数据,k<=5,所有字符串总长L满足L <=100
对于30%的数据,L<=10000
对于60%的数据,L<=30000
对于100%的数据,n<=5,m<=5,1<=k<=L<=100000
保证所有DNA序列不为空且只会包含’A’ ’G’ ’C’ ’T’四种字母

资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms

====================

思路:
得到可能的序列(因为序列定长为m)
dfs搜索序列在生物组(数组)中出现的次数
(做的时候,感觉难度在于阅读理解)

总结:
一开始在考虑数据容器的时候,第一个想法:采用形如数组[物种(int)][序列(string)][次数(int)],但是细想一波,成本有点高,故弃掉了,改用String[][] 数组
在考虑遍历方式的时候,一开始是想根据数学公式构建一个排列组合的方法zuhe(int a ,int b),后面我又考虑到成本–dfs深度n只有5,所以…dfs真香

public class dfs_碱基_6 {
	static int n ,m ,k;
	static String[][] s;
	static long MOD =1000000007;
	static long ans;
	public static void main(String[] args) {
		init();
		//这波dfs()必须给出 头部情况
		for(int i =0 ;i <n -m +1 ;i ++) for(int j =0 ;j <s[i].length ;j ++) dfs(i +1 ,1 ,s[i][j]);
		System.out.println(ans %MOD);
	}
	/**
	 * @param lev		物种编号(索引)
	 * @param times		序列在该生物组(整个数组)中出现的次数
	 * @param str		正在搜索的序列
	 */
	private static void dfs(int lev ,int times ,String str) {
		if(times ==m) {ans ++ ; return ;}
		if(lev ==n) return ;
		//这波for(int i =lev ;i <n ;i ++)->因为顾及lev =1 3 4这类跳过没有该元素的一行的情况
		for(int i =lev ;i <n ;i ++) for(int j =0 ;j <s[i].length ;j ++) if(s[i][j].equals(str)) dfs(i +1 ,times +1 ,str);
	}
	private static void init() {
		Scanner sc = new Scanner(System.in);
		n =sc.nextInt();
		m =sc.nextInt();
		k =sc.nextInt();
		
		s =new String[n][];
		for(int i =0 ;i <n ;i ++) {
			String raw =sc.next();
			s[i] =new String[raw.length() -m +1];
			//因为每个二元组的长度为定长m,因此可以先得到可能的序列
			for(int j =0 ;j <s[i].length ;j ++) s[i][j] =raw.substring(j ,j +m); 
		}	
		sc.close();
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43638238/article/details/107653792
今日推荐