码迷,mamicode.com
首页 > 其他好文 > 详细

HihoCoder 基因工程

时间:2020-03-11 09:13:58      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:class   次数   input   inf   规则   while   int   bsp   inpu   

原题链接 http://hihocoder.com/problemset/problem/1052

问题:给定由ATCG组成的长度为N的字符串S,求解最少的改动次数,使得前K个字符序列与后K个字符序列相同,其中 1  <= K <= N

分析:

1)对于长度相同的两个字符串 A 和 B 来说,要将两个字符串变为相同,只需改动所有 Ai != Bi 的地方,令 Ai = Bi 或者 Bi = Ai 即可;

技术图片

2)当 K <= N / 2 时,前K个字符序列 与 后K个字符序列 没有交集,因此按照1)处理即可;

技术图片

3)当 K > N / 2 时,前K个字符序列 与 后K个字符序列 存在交集,如下图所示:

技术图片

为了方便描述,取 m = n - k,为满足前K个字符序列 与 后K个字符序列相同,S中的元素必须满足如下图所示的相等关系:

技术图片

这些相等关系约束,相当于将S划分为以下几个字符集合 U0 = {S0, Sm, ..., Sj*m},U1 = {S1, Sm+1, ..., Sj*m+1},...,Ui = {Si, Sm+i ... Sj*m+i},其中 i < m 且 Sj*m+i < N。针对每一个集合Ui,只需保持出现次数最多的字符不变,将其他字符替换成该字符即可,需修改次数 = 字符总数 - 出现最多的字符数。显然,当 K > N / 2时,同样可以这样处理,只是此时每个集合Ui只包含两个元素。

规则如下:

1)依次遍历每个集合 U0 = {S0, Sm, ..., Sj*m},U1 = {S1, Sm+1, ..., Sj*m+1},...,Ui = {Si, Sm+i ... Sj*m+i},其中 i < min(m, k) 且 Sj*m+i < N

2)针对每个集合,需修改次数 = 字符总数 - 出现最多的字符数

3)累加每个集合的需修改次数即可

代码如下:

 1 def solve():
 2     T = int(input())
 3     for i in range(T):
 4         S = raw_input()
 5         K = int(raw_input())
 6         ret = do_solve(S.strip(" "), K)
 7         print(str(ret))
 8 
 9 
10 def do_solve(S, K):
11     ret = 0
12     step = len(S) - K
13     cnt = [0, 0, 0, 0]
14     for i in range(min(K, step)):
15         cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0
16         j = i
17         while j < len(S):
18             if S[j] == A:
19                 cnt[0] = cnt[0] + 1
20             elif S[j] == T:
21                 cnt[1] = cnt[1] + 1
22             elif S[j] == C:
23                 cnt[2] = cnt[2] + 1
24             elif S[j] == G:
25                 cnt[3] = cnt[3] + 1
26             j += step
27         ret += sum(cnt) - max(cnt)
28     return ret
29 
30 
31 solve()

HihoCoder 基因工程

标签:class   次数   input   inf   规则   while   int   bsp   inpu   

原文地址:https://www.cnblogs.com/moderate-fish/p/12446073.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!