题目大意

给出一个字符串(长度<=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;
}

hiho_1052_基因工程的更多相关文章

  1. hihocoder #1052 基因工程

    传送门:基因工程 这道题拖了好久,一直没有清晰的思路. 当然,$K\le\frac{N}{2}$时,比较简单.下面我着重讲一下当$K>\frac{N}{2}$,即前$K$个字符与后$K$个字符有 ...

  2. hihocoder #1052 : 基因工程(字符串处理 + 找规律 )

    #1052 : 基因工程 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho正在进行一项基因工程实验.他们要修改一段长度为N的DNA序列,使得这段DNA上最前面 ...

  3. 【HIHOCODER 1052 】基因工程(贪心)

    链接 问题描述 小Hi和小Ho正在进行一项基因工程实验.他们要修改一段长度为N的DNA序列,使得这段DNA上最前面的K个碱基组成的序列与最后面的K个碱基组成的序列完全一致. 例如对于序列"A ...

  4. HihoCoder1052基因工程(简单模拟题)

    描述 小Hi和小Ho正在进行一项基因工程实验.他们要修改一段长度为N的DNA序列,使得这段DNA上最前面的K个碱基组成的序列与最后面的K个碱基组成的序列完全一致. 例如对于序列"ATCGAT ...

  5. HihoCoder#1052:基因工程

    HihoCoder#1052:基因工程 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho正在进行一项基因工程实验.他们要修改一段长度为N的DNA序列,使得这段 ...

  6. hihoCoder 1052 基因工程 最详细的解题报告

    题目来源:基因工程 解题思路:假设基因序列长度为N,则需要计算基因序列前K个和后K个相同所需要的最少改变次数sum. 假设基因序列为 ATACGTCT (即M=8),K=6:interval=M-K= ...

  7. [HIHO1052]基因工程(找规律)

    题目链接:http://hihocoder.com/problemset/problem/1052 题意:中文题面,就是修改其中几个字符,使得[0,k-1]和[n-k,n-1]的字符相同. 会发现一个 ...

  8. 【xsy1012】KSHKM的基因工程 AC自动机DP

    题目大意:给你$n$个串$p_i$,最后再给一个串$s$(字符集均为A,C,G,T四个字符中的一个).问你串$s$最少要更改多少个字符(更改后的字符也只能是ACGT),才能满足s中不包含$p_i$$( ...

  9. LOJ2778 [BOI2018]基因工程 随机化

    题面 不想写了...留坑吧... 基本思想可参照随机化解决判同问题的总结 代码: #include<bits/stdc++.h> using namespace std; #define ...

随机推荐

  1. jquery uploadify上传插件兼容火狐问题

    jquery uploadify长传插件兼容火狐问题.因为现在火狐以不在默认安装flash插件.所以uploadify的flash版就需要安装flash插件.还可以成功. 可以到哪里下载安装:http ...

  2. 2016年10月24日 星期一 --出埃及记 Exodus 19:8

    2016年10月24日 星期一 --出埃及记 Exodus 19:8 The people all responded together, "We will do everything th ...

  3. program

    [题目分析] 题目的意思是在一个数列中找到四个数,a[i]=a[j]<a[k]=a[l],其他都扯淡. 先把这些数sort一下,所有相等的数字就都排在一起了,然后这个数列可以按照数字的种类划分成 ...

  4. android 入门 003 (点击事件)

    点击事件 有四种实现方式. 1.内部类实现方式 1.0 package cn.rfvip.clickevent; import android.app.Activity; import android ...

  5. nginx fastcgi 超时问题解决记录

    在网站后台导数据时,出现超时的情况.经过网上查找资料和试验 主要在下面几个配置的限制 1.php配置 第一种:set_time_limit(0); 永不过期 第二种: php.ini   max_ex ...

  6. HDU 4997 Biconnected (状态压缩DP)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4997 题意:一个n个点的完全图中去掉一些边.求这个图有多少个子图是边双联通的.(就是去掉任意一条边之后 ...

  7. BZOJ 2132 圈地计划(最小割)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2132 题意:n*m的格子染色黑白,对于格子(i,j)染黑色则价值为A[i][j],白色为 ...

  8. unity3d 游戏对象消失三种方法的区别(enabled/Destroy/active)

    gameObject.renderer.enabled //是控制一个物体是否在屏幕上渲染或显示 而物体实际还是存在的 只是想当于隐身 而物体本身的碰撞体还依然存在的 GameObject.Destr ...

  9. jquery之html(),text()方法详解

    一:html() html()函数用于设置或返回当前jQuery对象所匹配的DOM元素内的html内容. 该函数的用途相当于设置或获取DOM元素的innerHTML属性值. 该函数属于jQuery对象 ...

  10. Django serializers 序列化 rest_framework

    参考官方文档1(你懂的):http://www.django-rest-framework.org/api-guide/serializers/ 参考官方文档2(你懂的):http://www.dja ...