您的位置:首页 > 其它

hiho_1052_基因工程

2016-05-20 21:04 387 查看

题目大意

给出一个字符串(长度<=1000),字符串中的字符均为ATCG中的某一个。给出一个数字K,通过更改字符串中的某些字符,可以使得字符串的前K个字符形成的子串和最后K个字符形成的子串相同,求出最少更改的字符个数。

分析

理解题意,画图之后,仿佛是KMP的结果,但是这和KMP没啥关系...画图分析之后,知道问题应该分情况讨论:记 len 为字符串的长度,result为最少更改的字符个数。
(1) len >= 2*K
两个子串中间没有重合,直接进行比较相应位置上的字符,不同result就加1
(2)len - K > K / 2
两个子串中间有重合,但是分析发现,需要加整个字符串分两个部分进行分别统计。t = 2*K-len. [t, K-t), [K-t, 2*(k-t)) 这两个区域应该相同; 且[0, t), [K-t, K), [len - t, len) 这三个区域相同。
(3)len -K <= K / 2
画图可以知道,此时这个len长度的字符串被分成了连续的长度为(len - K)的一段段的子串,这些子串必须相同,最后一个子串可能长度没有(len - K),它就是前面那些子串的前缀。这样就需要判断,将len长度的字符串分割成连续的长度为(len - K)的子串,需要最少改动多少个字符使得这些子串相同。由于每个位置的字符只能为 ATCG中的一个,因此可以维护数组 gcount[len-K][4],其中 gcount[i][c] 表示 那些子串在各自的i位置上的字符为c(将A映射为0,T为1,C为2,G为3)的个数。遍历完一遍母串之后,求出gcount数组,对于每个位置i,都可以求出gcount[i]中的和 sum,以及最大值 max,sum-max即为需要发生的变动,将所有的位置处需要发生的变动加和。

实现

#pragma once
#pragma execution_character_set("utf-8")
// 本文件为utf-8 编码格式

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char gene[1005];
int gcount[1005][4];
int main(){
int T, k;
scanf("%d", &T);
while (T--){
getchar();
scanf("%s", gene);
scanf("%d", &k);
int len = strlen(gene);
int result = 0;
if (len <= k){
result = 0;
}
else if (len >= 2 * k){
for (int i = 0; i < k; i++){
if (gene[i] != gene[i + len - k])
result++;
}
}
else if(len - k > k / 2){
int t = 2 * k - len;
for (int i = t; i < k - t; i++){
if (gene[i] != gene[i + k - t])
result++;
}
for (int i = 0; i < t; i++){
char a = gene[i];
char b = gene[i + k - t];
char c = gene[i + len - t];
if (a == b){
if (a != c)
result++;
}
else if (a == c){
if (a != b)
result++;
}
else if (b == c){
if (b != a)
result++;
}
else
result += 2;
}

}
else{
memset(gcount, 0, sizeof(gcount));
for (int i = 0; i < len; i++){
int index = i % (len - k);
if (gene[i] == 'A')
gcount[index][0]++;
else if (gene[i] == 'T')
gcount[index][1] ++;
else if (gene[i] == 'C')
gcount[index][2] ++;
else if (gene[i] == 'G')
gcount[index][3] ++;
}
for (int index = 0; index < (len - k); index++){
int sum = 0, max = 0;
for (int i = 0; i < 4; i++){
sum += gcount[index][i];
max = max > gcount[index][i] ? max : gcount[index][i];
}
result += (sum - max);
}
}
printf("%d\n", result);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: