《信息学奥赛一本通》第 110 题:基因相关性
题目描述
为了获知基因序列在功能和结构上的相似性,经常需要将几条不同序列的 DNA 进行比对,以判断该比对的 DNA 是否具有相关性。
现比对两条长度相同的 DNA 序列。首先定义两条 DNA 序列相同位置的碱基为一个碱基对,如果一个碱基对中的两个碱基相同的话,则称为相同碱基对。接着计算相同碱基对占总碱基对数量的比例,如果该比例大于等于给定阈值时则判定该两条 DNA 序列是相关的,否则不相关。
输入格式
有三行,第一行是用来判定出两条 DNA 序列是否相关的阈值,随后 2 2 2 行是两条 DNA 序列(长度不大于 500 500 500)。
输出格式
若两条 DNA 序列相关,则输出yes
,否则输出no
。
输入输出样例 #1
输入 #1
0.85
ATCGCCGTAAGTAACGGTTTTAAATAGGCC
ATCGCCGGAAGTAACGGTCTTAAATAGGCC
输出 #1
yes
大家好,我是莫小特。
这篇文章给大家带来《信息学奥赛一本通》中的一百一十题:基因相关性。
一、题目描述
洛谷的题号是:B2111 基因相关性
二、题意分析
这道题是信息学奥赛一本通练习题的第 110 题,考察的是字符数组的应用。
根据输入格式的描述,输入有三行,第一行是用来判定两条 DNA 是否相关的阈值,根据样例输入的数据,可知这个数是小数,使用 double 类型。
double yz;
cin>>yz;
随后两行是 DNA 序列,长度不大于 500,所以可以使用字符数组。
char str1[600];
char str2[600];
根据样例输入的情况,这两个字符数组,中间并没有空格,所以直接使用 cin 来输入。
cin>>str1;
cin>>str2;
输入完成后,我们来分析题意。
根据题目描述,最终是要比对两条 DNA 序列是否具有相关性,也就是找相同位置上的碱基是否相同,所以我们需要先遍历该长度的 DNA 序列。
遍历字符数组,用到 strlen 函数,因为两个长度是相等的,所以直接使用一个长度就可以,遇到相同的碱基对,就进行统计,首先要定义一个累加器 cnt,初始值为 0。
int cnt=0;
for(int i=0;i<strlen(str1);i++)
{
if(str1[i]==str2[i])
{
cnt++;
}
}
统计完成后,将 cnt 除以整个长度,就可以求出相关性,因为是小数,所以计算时,要将数据进行强制转换,这样才方便比较。
double xgx;
xgx=(double)cnt/strlen(str1);
和输入的阈值进行比较。
if(xgx>=yz)
{
cout<<"yes";
}
else
{
cout<<"no";
}
按样例输入来测试数据。
提交到网站中进行测评。
完美通过!
三、完整代码
该题的完整代码如下:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
double yz;
cin>>yz;
char str1[600];
char str2[600];
cin>>str1;
cin>>str2;
int cnt=0;
for(int i=0;i<strlen(str1);i++)
{
if(str1[i]==str2[i])
{
cnt++;
}
}
double xgx;
xgx=(double)cnt/strlen(str1);
if(xgx>=yz)
{
cout<<"yes";
}
else
{
cout<<"no";
}
return 0;
}
四、总结
本题考察了字符串处理与小数计算,属于信息学竞赛中非常经典的题型。
掌握以下几点,可以帮助你轻松拿下类似题目:
-
输入多行数据的处理技巧:注意题目中三行输入,第一行为
double
类型的阈值,后两行为不含空格的 DNA 序列,可直接使用cin
输入字符数组。 -
字符串长度的计算:使用
strlen()
函数统计字符串长度。因为题目说明两个 DNA 序列等长,所以可以只取一个长度。 -
字符逐位比较:通过遍历字符数组,判断两个字符串对应位置的字符是否相同,统计相同碱基对的个数。
-
比例计算中的强制类型转换:
cnt / strlen(str1)
中需注意类型转换,避免整数除法导致误判。可写作(double)cnt / strlen(str1)
。 -
浮点数比较的基本技巧:本题要求判断相似度是否大于等于某个
double
阈值,需保证精度正确,不能直接用int
比较。
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、关注我哦!
如果有更好的方法也可以在评论区评论哦,我都会看哒~
我们下集见~