参考程序:
cpp
#include <bits/stdc++.h>
using namespace std;
int minx(string s) {
int n = s.size();
int totalA = count(s.begin(), s.end(), 'A'); // 统计 'A' 的总数
// 可行性:要想奇偶位 A 数相等,A 总数必须为偶数
if (totalA % 2 == 1) return -1;
int target = totalA / 2; // 目标:奇数位上的 A 个数
int oddA = 0, evenA = 0;
// 统计初始奇/偶位置上的 A 个数(i 从 0 开始,所以 i%2==0 表示 1-based 奇数位)
for (int i = 0; i < n; ++i) {
if (s[i] == 'A') {
if ((i + 1) % 2 == 1) oddA++; // 1-based 奇数位
else evenA++; // 1-based 偶数位
}
}
// 如果已经满足条件,0 次交换
if (oddA == target) return 0;
int swaps = 0; // 记录最少交换次数
// 从左到右扫描,遇到"放在多的一边的 A",就往前(右侧)找一个"对边的 B"来交换
for (int i = 0; i < n; ++i) {
if (oddA == target) break; // 够了就停
// 情况1:当前是奇数位上的 A(1-based),而我们希望把奇数位 A 减少(oddA > target 时有效)
if ((i + 1) % 2 == 1 && s[i] == 'A') {
// 在 i 右侧寻找一个"偶数位上的 B"来交换(这样该 A 就跨到偶数位)
for (int j = i + 1; j < n; j++) {
if ((j + 1) % 2 == 0 && s[j] == 'B') {
swap(s[i], s[j]); // 直接对调,等价于做了 (j-i) 次相邻交换
swaps += j - i; // 累加交换步数
oddA--; // 该 A 已从奇数位移出
evenA++; // 偶数位 A 增加
break; // 处理下一个 i
}
}
// 情况2:当前是偶数位上的 A,而我们希望把偶数位 A 减少(oddA < target 时有效)
} else if ((i + 1) % 2 == 0 && s[i] == 'A') {
// 在 i 右侧寻找一个"奇数位上的 B"来交换
for (int j = i + 1; j < n; ++j) {
if ((j + 1) % 2 == 1 && s[j] == 'B') {
swap(s[i], s[j]);
swaps += j - i;
oddA++; // 该 A 已跨到奇数位
evenA--;
break;
}
}
}
}
// 若成功达到目标,返回累计交换次数;否则返回 -1(比如右侧找不到可交换的 B)
if (oddA == target) return swaps;
else return -1;
}
int main() {
string s;
cin >> s;
cout << minx(s) << endl;
return 0;
}