https://ac.nowcoder.com/acm/contest/7817/H
给你a g t c 让你两两交换最少的次数后,两个字符相等
如果 a--->g 而且 g---.a,就一步, a---->g, g ---->t, t --- >a(长度为三的环)置换两步。
由于只有四个字符存在,可以枚举长度为2的环,3的环和4 的环,尽管字符又1e6的边,但是四个点,重合就边权了,具体看代码很好理解。
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 200+11;
int id[maxn];
string sn,cn;
int map[20][20];
int n;
ll ans = 0;
int main() {
id['A'] = 1;
id['G'] = 2;
id['T'] = 3;
id['C'] = 4;
cin>>sn;
cin>>cn;
n = 4;
for(int i=0; i<sn.length(); i++) {
if(sn[i] == cn[i]) continue;
map[id[sn[i]]][id[cn[i]]] ++;
}
ans = 0;
//长度为2的环
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
int ln = min(map[i][j],map[j][i]);
ans += ln;
map[i][j] -= ln;
map[j][i] -= ln;
}
}
//长度为3的环
for(int i =1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
if(i == j || k == j || i == k) continue;
int ln = min(map[i][j],min(map[j][k],map[k][i]));
ans += 2*ln;
map[i][j] -= ln;
map[j][k] -= ln;
map[k][i] -= ln;
}
}
}
//长度为4 的环
for(int i =1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
for(int s=1;s<=n;s++){
if(i == j || j == k || k == s || j == k || s == k || s == j) continue;
int a = min(map[i][j],map[j][k]);
int b = min(map[k][s],map[s][i]);
int ln = min(a,b);
map[i][j] -= ln;
map[j][k] -= ln;
map[k][s] -= ln;
map[s][i] -= ln;
ans += 3*ln;
}
}
}
}
printf("%lld
",ans);
return 0;
}