给你一个二进制字符串 s (一个只由 0-s 和 1-s 组成的字符串)。
您可以对 s 进行两种操作:
1. 从 s 中删除一个字符。该操作需要花费 1 个硬币;
2. 交换 s 中的任意一对字符。该操作是免费的(需要花费 0 个金币)。
您可以任意次数和顺序执行这些操作。
让我们将执行上述操作后得到的字符串命名为 t 。如果从**1 到 |t|的每个 i** t _ i \neq s _ i 都是字符串 t ,那么这个字符串 t 就是好字符串。 |t| 是字符串 t 的长度)。空字符串总是好字符串。请注意,您正在比较结果字符串 t 和初始字符串 s 。
使字符串 t 变好的最小总成本是多少?
这道题其实我第一眼看到很懵逼,后面也是看了一下别人的想法写出来的,其实本质上是一个贪心的问题,首先你要计算一下1和0的值,而且居于他原本t1不能等于s1相当于一个取反,因为存在交换和删除,如果1的数量等于0,那么消耗为零,否则就要进行另一方面考虑,那么这点其实就是一个难点,其实我开始也是这样想的,但是其实不用可以这样来,比如是111100,就先通过二维数组计算出1和0的个数,然后通过计算出1的数量为4,0为2,则使用cnt[1-(s[i]-'0')]判断当0的数字为0时,那么计算总长度也就是s.length()-i就是答案.还有额外的情况也就是0,就可以用i=s.length进行判断,上代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int calculatePrefixLength(const string& s) {
vector<int> cnt(2, 0);
for (int i = 0; i < s.length(); ++i) {
cnt[s[i] - '0']++;//转换数字
}
for (int i = 0; i <= s.length(); ++i) {
if (i == s.length() || cnt[1 - (s[i] - '0')] == 0) {
return s.length() - i;
}
cnt[1 - (s[i] - '0')]--;
}
return 0;
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
string s;
cin >> s;
cout << calculatePrefixLength(s) << endl;
}
return 0;
}