题目
- 详细题目
- 题目分析(做了几道题,发现读懂题目真的很重要!)
- Hamming distance
- 汉明距离是以理查德·卫斯里·汉明的名字命名的。在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。
- the consensus string
- 共有序列(consensus sequence) 。DNA相关知识里的一个 名词
- 共有序列是在一套相似序列中的每个位置上都由最常出现的残基所组成的DNA或氨基酸序列。
- 由此可知,最后输出的字串是由输入DNA序列每列重复次数最多的字母组成。
- lexicographically 字典序
- If there exists more than one consensus string, print the lexicographically smallest consensus string.
- 以列的视角,如果一列上重复次数最多的字母不唯一,则按照字典序中最小的字母输出。
- DNA序列只有四个字母组成,A\C\G\T。只需要注意这四个字母的顺序。
- Hamming distance
思路
- 其实题目分析完就挺好写的,定义一个数组记录每列各个字母出现的次数count[c][4].注意记录的顺序一定要是A|C|G|T。
代码
#include<stdio.h>
#include<string.h>
int main(){
int T;
scanf("%d",&T);
while(T--){
int r,c;
scanf("%d %d",&r,&c);
char string[r][c];
int i,j;
//接收输入样例
for(i=0;i<r;i++)
scanf("%s",string[i]);
//记录每列每个字母出现的次数
int count[c][4]; //顺序必须是ACGT
memset(count,0,sizeof(count));
for(i=0;i<r;i++){
for(j=0;j<c;j++){
if(string[i][j] == 'A') count[j][0]+=1;
if(string[i][j] == 'C') count[j][1]+=1;
if(string[i][j] == 'G') count[j][2]+=1;
if(string[i][j] == 'T') count[j][3]+=1;
}
}
//输出
int sum=0,co; //co记录列
for(i=0;i<c;i++){
int max=count[i][0];
co=0;
for(j=0;j<4;j++){
if(count[i][j]>max){ //如果次数和目前的最大次数相等,不用改变最大次数对应的下标,因为之前存储次数的顺序就是按照字典序从小到大存储的
max=count[i][j]; //记录出现的最大次数
co=j; //记录出现次数最多的下标
}
}
if(co==0) printf("A");
else if(co==1) printf("C");
else if(co==2) printf("G");
else if(co==3) printf("T");
sum+=max; //重复的总次数
}
printf("\n");
sum=c*r-sum; //不重复的次数
printf("%d\n",sum);
}
}
相关知识
- 汉明距离 Hamming distance
- 汉明在误差检验与校正码的基础性论文中首次引入这个概念
- 汉明距离多用于信号处理,表明一个信号变成另一个信号需要的最小操作(替换位)。
- 比较两个比特串中有多少位不一样,只需要对两个比特串进行异或之后看包含1的个数。
- 应用
- 两张图片相似度的比较。利用“感知哈希算法”对每张图片生成一个“指纹”字符串,利用“汉明距离”比较不同的位数,不同的位数越少,两图片越相似。