ICPC Central Europe Regional Contest 2019 H. Ponk Warshall

Ponk Warshall

思路:容易想到如果存在  "AG" "GA"这种,那一定是先交换这些,可以一次交换解决两个位置,如果不存在前面的情况,我们需要找到类似"AG","GT"这种斜对角能抵消的,得到"AT"然后我们需要马上去找有无"AT","TA"这种情况的。

我们知道"ATCG"只会出现16种字符串长度为2的情况,我们可以暴力枚举情况,直到所有位置都被平行位置,复杂度一定是ok的。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <set>
  5 #include <vector>
  6 #include <cmath>
  7  #include <map>
  8 
  9 using namespace std;
 10  
 11 #define ll long long
 12 #define pb push_back
 13 #define fi first
 14 #define se second
 15 #define lson(x) (x << 1)
 16 #define rson(x) (x << 1 | 1)
 17 #define mid(l,r) ((l + r) >> 1)
 18 
 19 const int INF = 1e9;
 20 map<string, int> mp;
 21 
 22 void fun(string fi, int& ans, int& n){
 23     string a{"aa"}, b{"aa"}, c{"aa"};
 24     string se = "ATCG";
 25     //先匹配"AG" "GA"情况
 26     for(int i = 0; i < 4; ++i){
 27         for(int j = 0; j < 4; ++j){
 28             if(i == j) continue;
 29             a[0] = se[i]; a[1] = se[j];
 30             b[1] = a[0]; b[0] = a[1];
 31             int cnt = min(mp[a], mp[b]);
 32             ans += cnt;
 33             mp[a] -= cnt;
 34             mp[b] -= cnt;
 35             n -= 2 * cnt;
 36         }
 37     }
 38     for(int i = 0; i < 4; ++i){
 39         a[0] = fi[0]; a[1] = se[i];
 40         //"AA"情况
 41         if(a[0] == a[1]){
 42             n -= mp[a];
 43             mp[a] = 0;
 44         }else{
 45             //"AG" "GT"情况
 46             b[0] = a[1]; b[1] = a[0];
 47             int cnt = min(mp[a], mp[b]);
 48             ans += cnt;
 49             mp[a] -= cnt;
 50             mp[b] -= cnt;
 51             n -= 2 * cnt;
 52             for(int x = 0; x < 4; ++x){
 53                 if(se[x] == se[i] || se[x] == fi[0]) continue;
 54                 b[0] = se[i]; b[1] = se[x];
 55                 int cnt = min(mp[a], mp[b]);
 56                 ans += cnt;
 57                 mp[a] -= cnt;
 58                 mp[b] -= cnt;
 59                 n -= cnt;
 60                 //试探"AG" "GA"情况
 61                 c[0] = fi[0]; c[1] = se[x];
 62                 mp[c] += cnt;
 63                 b[0] = c[1]; b[1] = c[0];
 64                 cnt = min(mp[b], mp[c]);
 65                 ans += cnt;
 66                 mp[b] -= cnt;
 67                 mp[c] -= cnt;
 68                 n -= 2 * cnt;
 69             }
 70         }
 71     }
 72    // cout << n << endl;
 73 }
 74 
 75 void solve(){
 76     
 77     mp["AA"] = 0;
 78     mp["AT"] = 0;
 79     mp["AC"] = 0;
 80     mp["AG"] = 0;
 81     mp["TA"] = 0;
 82     mp["TT"] = 0;
 83     mp["TC"] = 0;
 84     mp["TG"] = 0;
 85     mp["CA"] = 0;
 86     mp["CT"] = 0;
 87     mp["CC"] = 0;
 88     mp["CG"] = 0;
 89     mp["GA"] = 0;
 90     mp["GT"] = 0;
 91     mp["GC"] = 0;
 92     mp["GG"] = 0;
 93     string up, down;
 94     cin >> up >> down;
 95     int n = up.length();
 96     //cout << "length = " << n << endl;
 97     int ans = 0;
 98     string tmp{"aa"};
 99     for(int i = 0; i < n; ++i){
100         tmp[0] = up[i];
101         tmp[1] = down[i];
102         ++mp[tmp];
103     }
104     while(n){
105         fun("A", ans, n);
106         fun("T", ans, n);    
107         fun("C", ans, n);
108         fun("G", ans, n);
109     }
110 
111     cout << ans << endl;
112 }
113  
114 int main(){
115      
116      ios::sync_with_stdio(false);
117      cin.tie(0); cout.tie(0);
118      // freopen("C:\Users\admin\Desktop\input.txt", "w", stdin);
119      // freopen("C:\Users\admin\Desktop\output.txt", "r", stdout);
120     solve();
121  
122     return 0;
123 }
原文地址:https://www.cnblogs.com/SSummerZzz/p/12912591.html