你有一个由字符0、1和/或?组成的字符串s,我们称之为模式。如果你可以将每个字符?替换为0或1(对于每个字符,选择是独立的),使得字符串相等,则可以说二进制字符串(每个字符都是0或1的字符串)与该模式匹配。例如,0010与?01?匹配,但010不与1??,??或???匹配。我们定义二进制字符串的成本为将字符串排序为非降序所需的形式“反转字符串的任意连续子字符串”的最小操作次数。你需要在与给定模式匹配的二进制字符串中找到可能成本最小的字符串。如果有多个答案,请随意输出一个。c++代码
时间: 2024-02-13 15:05:16 浏览: 114
C++数据结构(第2版)课件第4章字符串和多维数组.ppt
以下是一个用C++实现的解决方案,可以找到与给定模式匹配且成本最小的二进制字符串:
```c++
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
int n = s.size();
vector<int> zeros(n), ones(n);
// 计算前缀中 0 和 1 的数量
zeros[0] = (s[0] == '0' || s[0] == '?') ? 1 : 0;
ones[0] = (s[0] == '1' || s[0] == '?') ? 1 : 0;
for (int i = 1; i < n; i++) {
zeros[i] = zeros[i - 1] + ((s[i] == '0' || s[i] == '?') ? 1 : 0);
ones[i] = ones[i - 1] + ((s[i] == '1' || s[i] == '?') ? 1 : 0);
}
// 找到最小成本
int cost = INT_MAX;
int best_i = -1;
for (int i = 0; i < n; i++) {
int cur_cost = 0;
// 计算反转前缀 [0, i] 的成本
cur_cost += ones[i] - zeros[i];
if (i < n - 1) {
// 计算反转后缀 [i+1, n-1] 的成本
cur_cost += zeros[n - 1] - zeros[i];
cur_cost -= ones[n - 1] - ones[i];
}
cost = min(cost, cur_cost);
}
// 构造二进制字符串
string ans(n, '0');
int cnt_0 = 0, cnt_1 = 0;
for (int i = n - 1; i >= 0; i--) {
if (s[i] == '0') {
ans[i] = '0';
cnt_0++;
} else if (s[i] == '1') {
ans[i] = '1';
cnt_1++;
} else {
if (cnt_0 + zeros[i] < cnt_1 + ones[i]) {
ans[i] = '0';
cnt_0++;
} else {
ans[i] = '1';
cnt_1++;
}
}
}
cout << ans << endl;
return 0;
}
```
该算法的时间复杂度为O(n),其中n是字符串s的长度。
阅读全文