题目描述:输入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序列和对应的距离。如有多
解,要求为字典序最小的解。例如,对于下面5个DNA序列,最优解为TAAGATAC。
TATGATAC
TAAGCTAC
AAAGATCC
TGAGATAC
TAAGATGT
题目分析:题中引入了Hamming距离的定义,看似要与m个序列比较求最小和十分麻烦,实际上用通俗的语言描述就是:求每个序列的对应位置出现次数的最多的字母,然后输出。题目的描述其实就是这个意思,分别找出每一列哪个元素重复次数最多。输入的m行n列元素用二维数组a存储,为了方便引入另一个数组b,其值为a的'转置'(行和列互换),这样每次需要比较的元素就在一行中,方便放入函数的参数中(因为需要循环多次,故将求重复次数最多的字母的方法放入函数中),因为要计算次数并且求和,于是再引入一个数组q,其中存放的是每一列ACGT出现的次数,注意ACGT对应q[1]q[2]q[3]q[4],即按字典序从小到大的顺序存放,将ACGT按顺序对应起来之后,后面就不用再计算字典序的大小了。次数存放好后,找出数组q中最小的元素对应的下标,注意用从大到小逐个比较,这样小的数优先级在前,即就算有两个元素值相等,较小的也会覆盖之前的,对应到ACGT就是A的会覆盖CGT的,这样就实现了字典序最小,不用再用多余的代码去算字典序。由于还要求最小距离和,故引用传参传入累加量,其值为数组b的列数,也就是DNA序列的个数m减去求出的最大出现次数,之后在函数外累加即可。函数最后就将出现次数对应回字母并返回。
代码如下:
//TEST
/*5 8
T A T G A T A C
T A A G C T A C
A A A G A T C C
T G A G A T A C
T A A G A T G T
RESULT
TAAGATAC
7
*/
#include <iostream>
using namespace std;
int findmin(char *x,int len,int &y){//注意要传入元素个数确定界限,累加量要用引用传入
int m=0,n,q[5]={0};
for(int k=0;k<len;k++)
switch(x[k]){
case 'A':
q[1]++;
break;
case 'C':
q[2]++;
break;
case 'G':
q[3]++;
break;
case 'T':
q[4]++;
break;
}
for(int i=4;i>0;i--)
if(q[i]>m) {m=q[i];n=i;}//求出出现字数最多的字母,同时计算了其中最小的字典序
y=len-q[n];//距离累加量
switch(n){//最后对应回去,返回字符
case 1:
return 'A';
break;
case 2:
return 'C';
break;
case 3:
return 'G';
break;
case 4:
return 'T';
break;
}
}
int main()
{
int m,n,s,sum=0;
char a[55][1010],b[55],c[1010][55];
cin>>m>>n;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
cin>>a[i][j];
c[j][i]=a[i][j];//c数组即将a数组的行列互换,方便比较
}
for(int i=0;i<n;i++)
{
b[i]=findmin(c[i],m,s);//该函数将返回每一列出现次数最多的字母
sum+=s;//每一列都需要累加距离
}
for(int i=0;i<n;i++)
cout<<b[i];
cout<<endl;
cout<<sum<<endl;
return 0;
}
总结:
一开始是打算先求出距离最小和序列的,然后再计算字典序,但发现这样十分麻烦,而在计算最小和的过程中,发现可以巧妙的利用ACGT的顺序从而使求出的序列一定为字典序最小的序列。
该博客介绍了如何解决ACM/ICPC Seoul 2006和UVa1368题目的问题,即给定多个DNA序列,找到一个序列使其与所有输入序列的Hamming距离之和最小,并且结果序列字典序最小。通过分析,博主提出了一种方法,通过计算每个位置上出现次数最多的碱基,来确定最终的DNA序列。在实现过程中,利用ACGT的字典序避免了额外的排序步骤,同时记录每个位置的碱基出现次数,从而得到最小Hamming距离和的解决方案。
&spm=1001.2101.3001.5002&articleId=102732109&d=1&t=3&u=238980095a6b46f4a8cf625fa74c503a)
2203

被折叠的 条评论
为什么被折叠?



