信友队
problemId:4304
Day1 T4
题意:
给你一个 0/1 串,你可以反转一个字符,或是把连续一段的相等的字符变成那个字符,求最少多少此可以让这个字符串变成每个字符都相等。
思路:
可以考虑 1101 和 0010 这种情况,因为这种情况可以把 1 变 0 或把 0 变 1 可以使答案更小(因为这样只需要一次操作就可以使两个块联通),然后除了这两种,剩下的就只需要合并,翻转即可。
\texttt{AC Code}
#include <bits/stdc++.h>
using namespace std;
int T;
string s;
int main() {
scanf("%d", &T);
while (T--) {
cin >> s;
string s1 = s;
int ans1 = 0;
for (int i = 0; i < (int)s.size(); ++i) {
if ((i + 3 < s.size()) && (s[i] == '1') && (s[i + 1] == '1') && (s[i + 2] == '0') && s[i + 3] == '1') {
ans1++;
s[i + 2] = '1';
}
}
for (int i = 0; i < (int)s.size(); ++i) {
int cnt = 0;
while (i < s.size() && s[i] == '1') {
cnt++;
i++;
}
if (cnt > 1) ans1++;
if (cnt > 0) ans1++;
}
int ans2 = 0;
s = s1;
for (int i = 0; i < (int)s.size(); ++i) {
if ((i + 3 < s.size()) && (s[i] == '0') && (s[i + 1] == '0') && (s[i + 2] == '1') && s[i + 3] == '0') {
ans2++;
s[i + 2] = '0';
}
}
for (int i = 0; i < (int)s.size(); ++i) {
int cnt = 0;
while (i < s.size() && s[i] == '0') {
cnt++;
i++;
}
if (cnt > 1) ans2++;
if (cnt > 0) ans2++;
}
printf("%d\n", min(ans1, ans2));
}
return 0;
}