UVA - 1368. DNA Consensus String

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/richenyunqi/article/details/82184492

UVA - 1368. DNA Consensus String题解

欢迎访问我的Uva题解目录https://blog.csdn.net/richenyunqi/article/details/81149109

题目描述

UVA - 1368. DNA Consensus String题目描述

题意解析

输入m个长度均为n的DNA序列,求一个DNA序列,到所有序列的总Hamming距离尽量小。两个等长字符串的Hamming距离等于字符不同的位置个数,例如,ACGT和GCGA的Hamming距离为2(左数第1, 4个字符不同)。输入整数m和n(4≤m≤50, 4≤n≤1000),以及m个长度为n的DNA序列(只包含字母A,C,G,T),输出到m个序列的Hamming距离和最小的DNA序列和对应的距离。如有多解,要求为字典序最小的解。

算法设计

为使Hamming距离和最小,可以找到输入字符串中相应位置下出现次数最多的字符作为所求DNA序列相应位置的字符,则该位置对应的距离即为m-该字符出现的次数。例如对以下4个DNA序列来说:

索引 0 1 2 3
序列1 T A T G
序列2 T A A G
序列3 A A A G
序列4 T G T G
应输出序列 T A A G
Hamming距离 1 1 2 0

在索引0处,4个DNA序列中出现次数最多的字符是T,故应输出DNA序列在该位置的字符为T,该位置的Hamming距离为4(共有4个DNA序列)-3(T字符出现了3次)=1。其余位置也如此计算。注意当多个字符出现次数相同时需取字典序小的。

C++代码

#include<bits/stdc++.h>
#define _for(i,a,b) for(int i=(a);i<(b);++i)//for循环的一种简单写法的宏定义
using namespace std;
int main(){
    int T,m,n;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&m,&n);
        string input[m];
        _for(i,0,m) cin>>input[i];//读入m个字符串
        map<char,int>um;//存储m个字符串中相同位置出现的字符及其对应的次数,注意map按键有小到大的顺序存储
        int error=0;//存储Hamming距离和
        _for(i,0,n){
            _for(j,0,m) ++um[input[j][i]];
            char MAX='A';
            for(auto&j:um)//查找出现次数最多的字符
                if(j.second>um[MAX])
                    MAX=j.first;
            putchar(MAX);//输出出现次数最多的字符
            error+=m-um[MAX];//加上Hamming距离
            um.clear();//清空map
        }
        printf("\n%d\n",error);//输出Hamming距离和
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/richenyunqi/article/details/82184492