CF1864B Swap and Reverse

发布时间 2023-08-31 17:23:40作者: -白简-

题目大意

给定一个长度为 \(n\) 的字符串 \(s\) 和一个整数 \(k\)

你可以进行若干次操作:

  • 选取一个 \(i\)\(1\le i\le n-2\)),交换 \(a_i\)\(a_{i+2}\)

  • 选取一个 \(i\)\(1\le i\le n-k+1\)),翻转区间 \(s_{[i,i+k-1]}\)

输出经过若干次操作后得到的的按字典顺序排列的最小字符串。

思路

第一个操作显然是奇偶性相同的字符之间可以相互交换,那么我们考虑第二个操作,看看我们第二个操作能否使得奇偶性不同的字符间发生互换。

分情况讨论:

  • \(i\) 为奇数,如果有 \(i+k-1\) 为偶数,那么 \(k\) 为偶数;
  • \(i\) 为偶数,如果有 \(i+k-1\) 为奇数,那么 \(k\) 也为偶数。

所以,只有当 \(k\) 为偶数时,才能够使得奇偶性不同的字符之间发生互换。

直接在可以互换的字符之间按照要求排序就行了。

Code

void Work() {
    cin >> n >> k;
    cin >> st;

    if((k - 1) % 2) {
        sort(st.begin(),st.end());

        cout << st << "\n";
    }
    else {
        string odd = "",even = "";
        for(int i = 0;i < st.size(); i++) {
            if(i % 2 == 0)
                odd += st[i];
            else
                even += st[i];
        }

        sort(odd.begin(),odd.end());
        sort(even.begin(),even.end());

        for(int i = 0;i < st.size(); i++) {
            if(i % 2 == 0)
                cout << odd[i / 2];
            else
                cout << even[i / 2];
        }
        cout << endl;
    }
    return ;
}