hiho_1052_基因工程

时间:2021-11-25 09:24:34

题目大意

给出一个字符串(长度<=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 &num;1052 基因工程

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

  2. hihocoder &num;1052 &colon; 基因工程&lpar;字符串处理 &plus; 找规律 &rpar;

    #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&num;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. &lbrack;HIHO1052&rsqb;基因工程(找规律)

    题目链接: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 &lbrack;BOI2018&rsqb;基因工程 随机化

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

随机推荐

  1. 【测试】自行建表并演示append&plus;nologging,并描述数据写入后产生的效果

    ①创建表: SQL> create table t4 as select * from all_objects; Table created. ②设置t4处于nologging: SQL> ...

  2. 正则表达式删除指定的HTML 标签

    1.抓取某网页的数据后(比如描述),如果照原样显示的话,可能会因为它里面包含没有闭合的HTML标签而打乱了格式,也可能它里面用了比较让人 "费解" 的HTML标签,把预订的格式搅乱 ...

  3. Article Master Data Deviation

    Site data – Logistics DC / Logistics Store Where is the reference site decided when you maintain the ...

  4. STL set&lowbar;difference set&lowbar;intersection set&lowbar;union 操作

    以下是STL algorithm的几个函数,使用的条件是有序容器,所以 vector在被sort了之后是可以使用的,set也是可以使用的. set_difference 这个是求得在第一个容器中有,第 ...

  5. T-SQL基础 (存储过程,触发器&vert;&vert; 笔记0808)

    一:存储过程 1.使用EXEC 调用存储过程 2.系统存储过程是以SP_开头,SP_ProcedureName.:例子:EXEC sp_columns TableName 查看列信息   扩展存储过程 ...

  6. C语言随记-1

    涉及指针.数组.函数指针 几种声明形式 int *a[5]; // a是一个有5个元素的数组,每个元素是整数类型指针(int *) int *a[] = {0x100, 0x104, 0x108, 0 ...

  7. status状态栏实现字符串走动

    <script type="text/javascript" language="javascript"> var i = 0; var str=& ...

  8. Android AVD启动报错:emulator&colon; ERROR&colon; x86&lowbar;64 emulation currently requires hardware acceleration&excl; Please ensure Intel HAXM is properly installed and usable&period;

    打开Android SDK manager查看安装发现HAXM在windows上无法安装 可以去 http://www.androiddevtools.cn/index.html 下载 Android ...

  9. C&plus;&plus;---使用VS在C&plus;&plus;编程中出现 fatal error C1010&colon; 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加&OpenCurlyDoubleQuote;&num;include &quot&semi;stdafx&period;h&quot&semi;”&quest;

    啦啦啦,好久没写博客啦... 对于C++初学者来说适应一个新的编译器还是需要蛮长一段时间的,现在我就给你们说说标题所说的这个问题吧... 第一步:菜单--〉项目--〉设置,出现“项目设置”对话框,左边 ...

  10. JavaScript实现元素拖动性能优化

    前言:前几天没事干写了个小网站,打算用原生的javascript实现元素的拖动,但是事情并没有想象的那么顺利,首先是实现了拖动的元素卡的不能再卡,简直不能够,上图~~ 看见没?这就是效果,简直让人欲哭 ...