I

题目描述
Listening to the rock music permutes your nuclear DNA. This astonishing and unbelievable fact was recently published in the Rock Nature Weekly, one of the top scientific journals on the planet. Part of the research was to take DNA samples from volunteers, both before and after the rock concerts season. The samples were processed and various genes isolated from the samples. For each person, each gene was isolated twice: The variant before the rock season and the variant after the season. These two variants were paired and in many cases one variant was found to be some permutation of the other variant in the pair.
The next step in the research is to determine how the permutations happen. The prevalent hypothesis suggests that a permutation is composed of a sequence of transpositions, so-called swaps. A swap is an event (its chemistry is not fully understood yet) in which exactly two nucleobases in the gene exchange their places in the gene. No other nucleobases in the gene are affected by the swap. The positions of the two swapped nucleobases might be completely arbitrary.
To predict and observe the movement of the molecules in the permutation process, the researchers need to know the theoretical minimum number of swaps which can produce a particular permutation of nucleobases in a gene. We remind you that the nuclear DNA gene is a sequence of nucleobases cytosine, guanine, adenine, and thymine, which are coded as C, G, A, and T, respectively.
输入
The input contains two text lines. Each line contains a string of N capital letters “A”, “C”, “G”,or “T”, (1 ≤ N ≤ 106 ). The two strings represent one pair of a particular gene versions. The first line represents the gene before the rock season, the second line represents the same gene from the same person after the rock season. The number of occurrences of each nucleobase is the same in both strings.
输出
Output the minimum number of swaps that transform the first gene version into the second one.
样例输入
CGATA
ATAGC
样例输出
2

题目大意
给定四种碱基对,两串DNA,问要经过几次交换才能使第一个变成第二个
思路
首先可以发现,上下两个位置不同的地方必须交换,那么有以下三种情况:
1.出现A-T, T-A这种的交换一次即可使两个位置正确
2.出现A-T, T-G, G-A这种的交换两次可以使得三个位置正确
3.出现A-T, T-C, C-G, G-A这样的需要交换三次才能使得4个位置正确
那么我们可以贪心的来找,先找第一种,再找第二种,最后找第三种,这样找出来的交换次数就是最划算的。
可以用一个二维数组存现有的对数。
代码

#include <iostream>
#include <map>

using namespace std;

const int N = 10;

int cnt[N][N];
map<char, int> m;
int ans;

int main()
{
    m['A'] = 0;
    m['T'] = 1;
    m['C'] = 2;
    m['G'] = 3;
    
    string a, b;
    cin >> a >> b;
    
    int len = a.size();
    for (int i = 0; i < len; i ++ )
    {
        if (a[i] == b[i]) continue;
        cnt[m[a[i]]][m[b[i]]] ++;  // 记录对数
    }
    
    for (int i = 0; i < 4; i ++ )
        for (int j = 0; j < 4; j ++ )
        {
            if (i == j) continue;
            int now = min(cnt[i][j], cnt[j][i]);
            ans += now;
            cnt[i][j] -= now;  // 让受影响的部分都减去
            cnt[j][i] -= now;
        }
        
    for (int i = 0; i < 4; i ++ )
        for (int j = 0; j < 4; j ++ )
            for (int k = 0; k < 4; k ++ )
            {
                if (i == j || i == k || j == k) continue;
                int now = min(cnt[i][j], min(cnt[k][i], cnt[j][k]));
                ans += now * 2;
                cnt[i][j] -= now;
                cnt[j][k] -= now;
                cnt[k][i] -= now;
            }
            
    for (int i = 0; i < 4; i ++ )
        ans += 3 * cnt[i][0];  // 还剩下的必定是需要交换3次的,只需要一次枚举即可
        
    cout << ans << endl;
    
    return 0;
}
posted on 2021-04-09 14:34  Laurance  阅读(378)  评论(0)    收藏  举报