题意:
给一些DNA序列(字符串只包含ACGT四种字母),求一个与这些DNA序列Hamming距离和最小的字符串,如果有多个这种字符串则输出字典序最小的那个,并求出最小Hamming距离和。
两个等长字符串的Hamming距离等于字符不同的位置的个数。
例如:ACGT和GCAT的Hamming距离是2.(左数第1,4个字符不同)
思路:
具体到每个位置考虑。最终的字符串在每个位置上的字母一定都是和输入DNA序列相应位置重合次数最多的那个。
因此只需统计输入所有DNA序列在每个位置重复出现字母次数。
用a[0][i], a[1][i], a[2][i], a[3][i]分别表示A,C,G,T在第i个位置(起始位置是0)出现的次数和
m-Max[i];Max[i]是输入DNA序列在位置i最大重合次数,即
Max[i] = max(a[0][i], a[1][i], a[2][i], a[3][i]);
s1[4] = { 'A','C','G','T' };
#include
#include
#define maxn 1010
int max(int a, int b, int c, int d, int *inde)
{
int max1;
max1 = a > b ? a : b;
max1 = max1 >= c ? max1 : c;
max1 = max1 >= d ? max1 : d;
if (max1 == a) *inde = 0;
else if (max1 == b) *inde = 1;
else if (max1 == c) *inde = 2;
else *inde = 3;
return max1;
}
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int T, m, n, i, j;
char s[50][maxn], s1[4] = { 'A','C','G','T' };
int a[4][maxn],index[maxn],Max[maxn];
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &m, &n);
for (i = 0;i < m;i++)
scanf("%s", s[i]);
memset(a, 0, sizeof(a));
for (i = 0;i < n;i++)
{
for (j = 0;j < m;j++)
{
if (s[j][i] == 'A') a[0][i]++;
else if (s[j][i] == 'C') a[1][i]++;
else if (s[j][i] == 'G') a[2][i]++;
else a[3][i]++;
}
Max[i] = max(a[0][i], a[1][i], a[2][i], a[3][i], &index[i]);
}
int dis = 0;
for (i = 0;i < n;i++)
{
putchar(s1[index[i]]);
dis += m - Max[i];
}
printf("\n%d\n", dis);
}
return 0;
}