Regionals 2006 >> Asia - Seoul
问题链接:UVA1368 UVALive3602 ZOJ3132 DNA Consensus String。
问题简述:给定m个长度为n的DNA序列,求一个DNA序列,使其到所有这些序列的总hamming距离尽量小,如果有多个解,输出字典顺序的最小解。
问题分析:
每个DNA序列的长度相同,对每个DNA序列的每一位DNA码进行统计,选取出现次数最多的码,那么这一位的hamming距离最小。依次类推,每一位都选取出现次数最多的码,那么这样的DNA序列到n个给定的DNA序列的总hamming距离就会最小。考虑这是一个典型的可以用贪心法解决的例子。
程序说明:
程序中,为了计算方便,先使用map将DNA码“ACGT”映射为整数0、1、2和3,这个映射是按字典顺序的。统计计算并且得到计算结果后再将整数0、1、2和3其映射为相应的DNA码“ACGT”。这样做可以简化程序逻辑,不用写许多条件语句了。
AC的C++语言程序如下:
/* UVA1368 UVALive3602 ZOJ3132 DNA Consensus String */ #include <iostream> #include <map> #include <cstring> #define MAXN 1000 int dnacount[MAXN][4]; using namespace std; int main() { int t, m, n, ans, i, j; map<char, int> dnamap; char dna[] = "ACGT", c; char result[MAXN+1]; dnamap['A'] = 0; dnamap['C'] = 1; dnamap['G'] = 2; dnamap['T'] = 3; scanf("%d", &t); while(t--) { scanf("%d%d", &m, &n); getchar(); memset(dnacount, 0, sizeof(dnacount)); for(i=0; i<m; i++) { for(j=0; j<n; j++) dnacount[j][dnamap[c = getchar()]]++; getchar(); } ans = m * n; for(i=0; i<n; i++) { int maxval = dnacount[i][0]; int maxindex = 0; for(j=1; j<4; j++) if(dnacount[i][j] > maxval) { maxval = dnacount[i][j]; maxindex = j; } ans -= maxval; result[i] = dna[maxindex]; } result[n] = ' '; printf("%s ", result); printf("%d ", ans); } return 0; }