Live2d Test Env

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

描述

小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   

题意:

给定一个字符串,问改变最小的字符,使得前k个字符和后k个字符相同。

思路:

模拟即可。然而我是用的dfs+排序,把有关系的分到一个组,然后这个组的最小改动=字符数目-最多的一种的数目。比如aaaabbc,肯定是把其他改成a。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1010;
int used[maxn];
char chr[maxn];
int cnt,q[maxn],K,L,ans;
void dfs(int x)
{
    used[x]=1;q[++cnt]=chr[x]-'A';
    if(x<=K&&!used[L-K+x]&&x-K+L<=L&&L-K+x>=1)  dfs(L-K+x);
    if(x>L-K&&!used[x+K-L]&&x+K-L<=L&&x+K-L>=1) dfs(x+K-L);
    return ;
}
int main()
{
    int T,i,j;
    scanf("%d",&T);
    while(T--){
        scanf("%s",chr+1);
        scanf("%d",&K);
        memset(used,0,sizeof(used));ans=0;
        L=strlen(chr+1);
        for(i=1;i<=L;i++){
          if(!used[i]&&(i<=K||i>L-K)){
             cnt=0;
             dfs(i);
             sort(q+1,q+cnt+1);
             int delta=0,tmp=0,pre=-2;
             for(j=1;j<=cnt;j++){
                    if(q[j]==pre) tmp++;
                    else {
                        delta=max(delta,tmp);
                        pre=q[j];tmp=1;
                    }
             }
             delta=max(delta,tmp);
             ans+=cnt-delta;
         }    
       } 
       printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2017-12-05 10:07  nimphy  阅读(291)  评论(0编辑  收藏  举报