zoukankan      html  css  js  c++  java
  • 【HIHOCODER 1052 】基因工程(贪心)

    链接

    问题描述

    小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

    题解

    第二组方案为ATATATAT,同时我们经过这一组数据也可以看出解法。
    AT=AC
    AC=GT
    GT=CT
    即AT=AC=GT=CT那么可以将这一组选出第一个统一的字母(出现最多的为最佳),第二个。。。。
    注意len%(len-k)!=0的情况

    参考代码

    import java.io.*;
    import java.util.*;
    public class Main {
    	static final int N = (int) 1e5 + 10;
    	static char a[] = new char[1005];
    	static char f[] = new char[1005];
    	static int vis[][] = new int[1005][1005];
        static int b[]= {0,'T'-'A','C'-'A','G'-'A'};
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(new InputStreamReader(System.in));
    		int T = sc.nextInt();
    		while (T-- != 0) {
    			String str = sc.next();
    			int k = sc.nextInt();
    			int len = str.length();
    			a = str.toCharArray();
    			int ans = 0;
    			if(k>=len) {
    				System.out.println(0);
    				continue;
    			}
    			if (k <= len / 2)
    				for (int i = 0, j = len - k; i < k; i++, j++) {
    					if (a[i] != a[j])
    						ans++;
    				}
    			else {
    				for (int i = 0; i < len - k; i++) {
    					for(int j=0;j<26;j++) vis[i][j]=0;
    				}
    				for (int i = 0; i < len; i += len - k) {
    					for (int j = i; j < i + len - k; j++) {
    						if(j>=len) break;
    						vis[j-i][a[j]-'A']++;
    					}
    				}
    				int mx,cnt;
    				for(int i=0;i<len-k;i++) {
    					mx=0;cnt=0;
    					for(int j=0;j<4;j++) {
    						if(vis[i][b[j]]>cnt) {
    							mx=b[j];cnt=vis[i][b[j]];
    						}
    					}
    					f[i]=(char)(mx+'A');
    				}
    				for (int i = 0; i < len; i += len - k) {
    					for (int j = i; j < i + len - k; j++) {
    						if(j>=len) break;
    						if (a[j] != f[j - i]) {
    							ans++;
    						}
    					}
    				}
    			}
    			System.out.println(ans);
    		}
    		sc.close();
    	}
    }
    
  • 相关阅读:
    代码品质
    窖藏好题
    最后一次模拟
    几个有意思的题目
    【数组练习】
    【复习】图论
    【复习】后缀数组
    The Usage Of Difference Table
    【复习】NTT注意事项
    CF999E Reachability from the Capital
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/7241558.html
Copyright © 2011-2022 走看看