• UVA


    //法一
    //这题算是初等贪心的思路了,要求总harmming距离最小,通过使每一位上选取的字母,都能使该位对总harming距离的贡献最小,按照定义,也就是所有DNA在该位置上,ATCG字母究竟哪个最多,若多个最多,就选字典序小的...思路确实挺巧妙,值得琢磨
    //顺带提一下,不知道为什么,看了别人的代码,发现有人将变量作为数组维度,即在main函数内部,char DNA[m][n+1];时,居然能AC,不是说数组的维度只能是常量吗?


    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1005;
    const int M = 50;
    char DNA[M][N];
    int num[4];
    
    int main()
    {
    	int t, m, n; //m是数目,n是长度
    	cin >> t;
    	while (t--)
    	{
    		int sum = 0;
    		cin >> m >> n;
    //		char DNA[m][n+1];
    		
    		for (int i = 0; i < m; i++) cin >> DNA[i];
    		for (int i = 0; i < n; i++) 
    		{
    			memset(num, 0, sizeof(num));
    			
    			for (int j = 0; j < m; j++)
    			switch(DNA[j][i])
    			{
    				case 'A' :num[0]++;break;
    				case 'C' :num[1]++;break;
    				case 'G' :num[2]++;break;
    				case 'T' :num[3]++;break;
    			}
    			
    			int temp = num[0], ans = 0;
    			for (int j = 1; j < 4; j++)
    			{
    				if (num[j] > temp)
    				{
    					ans = j; temp = num[j]; 
    				}
    			}
    			sum += m - temp;
    			
    			switch(ans)
    			{
    				case 0: cout << "A";break;
    				case 1: cout << "C";break;
    				case 2: cout << "G";break;
    				case 3: cout << "T";break;
    			}  
    		}
    		cout << endl << sum << endl;
    		
    	} 
    	return 0;
    }
    /*
      法二:
      
      用结构体真的能让代码简单很多很多...
     这个思路有个比较巧妙的地方,在于:将Harming距离所要求的,与对应字符不同的字符个数,转换为与对应字符相同的个数,然后再用总数(DNA个数)减去相同的个数
     
     其实不用这个思路也可以,但是会比较繁琐,例如我假设最终求得的那个DNA的,某个位置是A,那么所有m条DNA,对于每一条而言,如果对应的这个位置不是A,那么这个位置对应的GCT都要加1,繁琐且易错...而如果转变思路,用m减去相同的,需要更新的就只有该位置的A (这种思路下,记录的就是,当前位置下,ATCG分别会和几条DNA的该位置,对总harming距离作出贡献,这就真的是取最小值了)
    */

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1005;
    char check[N];
    char ans[N];
    struct DNA
    {
    	int a, c, g, t;
    	void clearall()
    	{
    		a = c = g = t = 0;
    	}
    	int getmax(char& ch)//此处很多地方要用偏序的不等号,因为有多个答案时,要输出字典序最小的...一开始忘了=号,结果答案错
    	{
    		ch = ( max(a, c) >= max(g, t) ? (a >= c? 'A':'C'):(g >= t? 'G' : 'T') );
    		return max( max(a, c), max(g, t) );
    	}
    }dna[N];
    
    
    int main()
    {
    	int t, m, n; //m是数目,n是长度
    	cin >> t;
    	while (t--)
    	{
    		int sum = 0;
    		cin >> m >> n;
    		for (int i = 0; i < n; i++)
    			dna[i].clearall();//一定是按照位置清空的,也就是DNA长度,而不是DNA数
    			
    		for (int i = 0; i < m; i++)
    		{
    			cin >> check;
    			for (int j = 0; j < n; j++)
    			switch(check[j])
    			{
    				case'A': dna[j].a++;break;
    				case'G': dna[j].g++;break;
    				case'C': dna[j].c++;break;
    				case'T': dna[j].t++;break;
    			}
    		}
    		
    		for (int i = 0; i < n; i++)
    		{
    			sum += m - dna[i].getmax(ans[i]);
    		}
    		ans[n] = '';
    		
    		cout << ans << endl << sum << endl;
    		
    	} 
    	return 0;
    }





  • 相关阅读:
    web网页测试用例(非常实用)
    怎么做web接口测试
    我的周记13——”离开,是为了更好的回来"
    Lambda 表达式常用函数
    IEnumberable<T>接口
    Linq的学习
    未能加载文件或程序集“Newtonsoft.Json”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。
    拉姆达表达式的笔记
    注册今日头条
    爬取百思不得姐的段子
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789506.html
Copyright © 2020-2023  润新知