1363B
题意:不能出现010或者101的子序列,求最小操作次数;
思路:最后改变完要不出现上述子序列,只能是连续一部分0和连续一部分1拼接成的字符串,可以通过求改变成这种字符串的最小次数求解;
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
using namespace std;
const int N = 200010;
typedef long long ll;
int s_1[N], s_0[N];
inline int read() {
int date = 0, w = 1; char c = 0;
while (c < '0' || c > '9') {if (c == '-')w = -1; c = getchar();}
while (c >= '0' && c <= '9') {date = date * 10 + c - '0'; c = getchar();}
return date * w;
}
inline void out(int x) {
if (x < 0) {putchar('-'); x = -x;}
if (x > 9) out(x / 10);
putchar(x % 10 + '0');
}
#define x first
#define y second
int main() {
int t = read();
while (t--) {
memset(s_0, 0, sizeof s_0);
memset(s_1, 0, sizeof s_1);
string s;
cin >> s;
for (int i = 0; i < s.size(); i++) {//pre...
if (s[i] == '0') s_0[i]++;
else s_1[i]++;
}
for (int i = 1; i < s.size(); i++) {
s_1[i] += s_1[i - 1];
s_0[i] += s_0[i - 1];
}
if (s.size() < 3) cout << 0 << endl;
else {
int ans = 0x3f3f3f3f;
int n = s.size();
ans = min(s_1[n - 1], s_0[n - 1]);
for (int i = 0; i < s.size(); i++) {
ans = min(ans, s_0[i] + s_1[n - 1] - s_1[i]); //the prefix is 1;
}
for (int i = 0; i < n - 1; i++) {
ans = min(ans, s_1[i] + s_0[n - 1] - s_0[i]); //the prefix is 0;
}
cout << ans << endl;
}
}
return 0;
}