UVA - 1368 DNA Consensus String

本文介绍了一个算法,用于从多个DNA序列中找出每列出现次数最多的核苷酸,并生成共识序列及错误计数。该算法首先读取测试用例数量及每个案例的序列数量和长度,然后逐个比较并统计每种核苷酸的出现次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Input 

Your program is to read from standard input. The input consists of  T test cases. The number of test cases  T is given in the first line of the input. Each test case starts with a line containing two integers  m and  n which are separated by a single space. The integer  m (4$ \le$m$ \le$50) represents the number of DNA sequences and  n (4$ \le$n$ \le$1000) represents the length of the DNA sequences, respectively. In each of the next  m lines, each DNA sequence is given.

Output 

Your program is to write to standard output. Print the consensus string in the first line of each case and the consensus error in the second line of each case. If there exists more than one consensus string, print the lexicographically smallest consensus string. The following shows sample input and output for three test cases.

Sample Input 

3 
5 8 
TATGATAC 
TAAGCTAC 
AAAGATCC 
TGAGATAC 
TAAGATGT 
4 10 
ACGTACGTAC 
CCGTACGTAG 
GCGTACGTAT 
TCGTACGTAA 
6 10 
ATGTTACCAT 
AAGTTACGAT 
AACAAAGCAA 
AAGTTACCTT 
AAGTTACCAA 
TACTTACCAA

Sample Output 

TAAGATAC 
7 
ACGTACGTAA 
6 
AAGTTACCAA 
12

分析:读取字符串,找到每列出现次数最多的字符。


#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
const int maxn = 1000 + 10;
int cnt[maxn][26];
char ans[maxn];

int main()
{
	int T;
	int m, n;
    string s;
	cin >> T;
	while(T--) {
		cin >> m >> n;
		memset(cnt, 0, sizeof(cnt));
		for(int i=0; i<m; i++) {
			cin >> s;
			for(int j=0; j<n; j++) {
				cnt[j][s[j]-'A']++;
			}
		}
		int diff = 0;
		for(int i=0; i<n; i++) {
			int total = 0, ch = 'A';
            for(int j=0; j<26; j++) {
				if(cnt[i][j]>total) {
					total = cnt[i][j];
					ch = 'A' + j;
				}
            }
            diff += m - total;
            ans[i] = ch;
		}
		for(int i=0; i<n; i++) putchar(ans[i]);
		printf("\n%d\n", diff);
	}
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值