Hihocoder-1052-基因工程
Hihocoder-1052-基因工程
#1052 : 基因工程
时间限制:1000ms
单点时限:1000ms
内存限制:256MB
描述
小Hi和小Ho正在进行一项基因工程实验。他们要修改一段长度为N的DNA序列,使得这段DNA上最前面的K个碱基组成的序列与最后面的K个碱基组成的序列完全一致。
例如对于序列"ATCGATAC"和K=2,可以通过将第二个碱基修改为"C"使得最前面2个碱基与最后面两个碱基都为"AC"。当然还存在其他修改方法,例如将最后一个碱基改为"T",或者直接将最前面两个和最后面两个碱基都修改为"GG"。
小Hi和小Ho希望知道在所有方法中,修改碱基最少的方法需要修改多少个碱基。
输入
第一行包含一个整数T(1 <= T <= 10),代表测试数据的数量。
每组测试数据包含2行,第一行是一个由"ATCG"4个大写字母组成的长度为N(1 <= N <= 1000)的字符串。第二行是一个整数K(1 <= K <= N)。
输出
对于每组数据输出最少需要修改的碱基数量。
- 样例输入
-
2 ATCGATAC 2 ATACGTCT 6
- 样例输出
-
1 3
题解:
对字符串的处理,发现有个规律;
(1), 当前k个字符和后k个字符没有相交, 则计算前后两串的不同字符的数量。
(2), 当有相交时候, 发现: 设string总长为 len, 要求的K长度的字符匹配, 那么, 前面部分的前缀为 len-k, 然后可以发现, 后面的字符都是这len-k的循环。
然后直接根据 len - k 这个循环节去count就ok了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
const int MAXN = 1005;
int main(){
int test_num, k, cnt, elem, total, cur_max, len;
char st[MAXN];
int vis[26];
scanf("%d", &test_num);
while(test_num--){
scanf("%s", &st);
scanf("%d", &k);
len = strlen(st);
cnt = 0;
if(len >= 2*k){
for(int i=0; i<k; ++i){
if(st[i] != st[len+i-k]){
cnt++;
}
}
}else if(k >= len){
cnt = 0;
}else{
elem = len - k;
for(int i=0; i<elem; ++i){
memset(vis, 0, sizeof(vis));
cur_max = 0; total = 0;
for(int j=i; j<len; j+=elem){
vis[ st[j]-'A' ] += 1;
total++;
if(vis[ st[j]-'A' ] > cur_max){
cur_max = vis[ st[j]-'A' ];
}
}
cnt += (total - cur_max);
}
}
printf("%d\n", cnt);
}
return 0;
}

浙公网安备 33010602011771号