给定一个字符串 S,定义操作为:将其中 [l_i,r_i] 字符都在 ASCII
数值意义下 +1,特别的,字母 z
+1 变成 a
。
问:你可以任意多次顺序执行k次操作,能否把S变为一个回文串?
第一行一个字符串 S。
接下来一行一个正整数 k,含义如题。
接下来 k 行,每行两个整数 [l,r] 表示操作的范围。
YES
或 NO
。
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
using namespace std;
bool canMakePalindrome(string s, int k) {
unordered_map<char, int> freq;
for (char c : s) {
freq[c]++;
}
vector<pair<char, int>> workList;
for (auto f : freq) {
char c = f.first;
int count = f.second;
if (count % 2 != 0) {
workList.push_back({c, count});
}
}
while (!workList.empty() && k > 0) {
char c = workList.back().first;
int count = workList.back().second;
workList.pop_back();
if (count % 2 != 0) {
if (k >= count / 2) {
k -= count / 2;
workList.push_back({c, count - count / 2});
} else {
return false;
}
}
}
return true;
}
int main() {
int k;
cin >> k;
string s;
int l, r;
for (int i = 0; i < k; i++) {
cin >> l >> r;
s.erase(l - 1, r - l + 2);
s.insert(l - 1, r - l + 2, 'a');
}
if (canMakePalindrome(s, k)) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
用字符串好像更简单,写一个专门判断是否为回文数的函数,然后每转换一次,调用一下回文函数
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
using namespace std;
bool canMakePalindrome(string s, int k) {
unordered_map<char, int> freq;
for (char c : s) {
freq[c]++;
}
vector<pair<char, int>> workList;
for (auto f : freq) {
char c = f.first;
int count = f.second;
if (count % 2 != 0) {
workList.push_back({c, count});
}
}
while (!workList.empty() && k > 0) {
char c = workList.back().first;
int count = workList.back().second;
workList.pop_back();
if (count % 2 != 0) {
if (k >= count / 2) {
k -= count / 2;
workList.push_back({c, count - count / 2});
} else {
return false;
}
}
}
return true;
}
int main() {
int k;
cin >> k;
string s;
int l, r;
for (int i = 0; i < k; i++) {
cin >> l >> r;
s.erase(l - 1, r - l + 2);
s.insert(l - 1, r - l + 2, 'a');
}
if (canMakePalindrome(s, k)) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
不知道你这个问题是否已经解决, 如果还没有解决的话:即如下图所示:
这样,我们就将小于基准数的数字全部放在了基准数的左边,大于基准数的全部放在了基准数的右边。
我们将基准数的左边的数字和基准数右边的数字分别进行上述所有步骤如下图,直至一个分支只有一个元素。