专栏文章

题解:CF2149D A and B

CF2149D题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mimxegci
此快照首次捕获于
2025/12/01 17:07
3 个月前
此快照最后确认于
2025/12/01 17:07
3 个月前
查看原文

方法思路

问题分析:

  • 目标是将所有'aa' 或所有 'bb' 集中成一个连续块,最小化相邻交换次数。
  • 相邻交换的次数等价于字符在原字符串中的位置与目标连续位置之间的逆序数。

核心观察:

  • 对于字符 'aa',假设共有 c个,它们在原字符串中的位置为 p。目标位置为 [k,k+1,...,k+c1][k, k+1, ..., k+c-1](其中 k 是起始位置),最小交换次数为这些位置的逆序数。
  • 同理,对于字符 'bb',计算其位置的逆序数。
  • 最终结果为两种字符逆序数的最小值。

算法选择:

  • 收集 'aa' 和 'bb' 在原字符串中的位置。
  • 计算每种字符位置列表的逆序数(通过计算每个位置与目标连续位置的差值之和)。
  • 比较两种逆序数,取最小值作为结果。

解决代码

CPP
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>  

using namespace std;

int main() {
    ios::sync_with_stdio(false); 
    cin.tie(nullptr);            

    int t;
    cin >> t;
    while (t--) {
        int n;
        string s;
        cin >> n >> s;

        vector<int> a, b;
        for (int i = 0; i < n; ++i) {
            if (s[i] == 'a') {
                a.push_back(i);
            } else {
                b.push_back(i);
            }
        }
        long long ca = 0;
        for (int i = 0; i < a.size(); ++i) {
            ca += a[i] - i;
        }
        long long cb = 0;
        for (int i = 0; i < b.size(); ++i) {
            cb += b[i] - i;
        }
        cout << min(c, cb) << '\n';
    }

    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...