CF1864B Swap and Reverse
题目大意
给定一个长度为 \(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 ;
}