#include <bits/stdc++.h>
using namespace std;
#define boost \
ios_base::sync_with_stdio(0); \
cin.tie(0); \
cout.tie(0)
pair<int, int> middle(const vector<int> &segments, int time) {
int saved = 0;
for (int x : segments) {
int possible_to_save = x - 2*time;
if (possible_to_save > 0) {
saved += possible_to_save - (possible_to_save > 1);
time += min(2, possible_to_save);
}
else {
break;
}
}
return {saved, time};
}
pair<int, int> boundary(int bound_val, int time) {
return {max(0, bound_val - time), time + max(0, min(bound_val - time, 1))};
}
int solve() {
int n;
cin >> n;
string s; cin >> s;
vector<int> segments;
vector<int> boundaries;
int seg_len = 0;
bool first_zero = (s[0] == '0');
for (char c : s) {
if (c == '0') {
seg_len += 1;
} else {
if (seg_len > 0) {
if (first_zero && segments.empty()) {
boundaries.push_back(seg_len);
first_zero = false;
} else {
segments.push_back(seg_len);
}
seg_len = 0;
}
}
}
if (seg_len == n)
return 0;
if (seg_len > 0) boundaries.push_back(seg_len);
sort(segments.begin(), segments.end(), greater<>());
sort(boundaries.begin(), boundaries.end(), greater<>());
int res = n;
for (int i = -1; i < int(boundaries.size()); ++i) {
int saved = 0, time = 0;
for (int j = 0; j <= i; ++j) {
auto b = boundary(boundaries[j], time);
saved += b.first, time = b.second;
}
auto b = middle(segments, time);
saved += b.first, time = b.second;
for (int j = i + 1; j < boundaries.size(); ++j) {
b = boundary(boundaries[j], time);
saved += b.first, time = b.second;
}
res = min(res, n - saved);
}
return res;
}
int main() {
boost;
int t;cin >> t;
for(int i = 0; i < t; ++i) {
cout << solve() << '\n';
}
return 0;
}
/**
5
4
1000
4
0100
4
0010
4
0001
4
1111
1
20
00001111001001111000
1
20
00011000000000001000
1
20
00101000101100100010
1
20
00000100000010000010
*/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | #include <bits/stdc++.h> using namespace std; #define boost \ ios_base::sync_with_stdio(0); \ cin.tie(0); \ cout.tie(0) pair<int, int> middle(const vector<int> &segments, int time) { int saved = 0; for (int x : segments) { int possible_to_save = x - 2*time; if (possible_to_save > 0) { saved += possible_to_save - (possible_to_save > 1); time += min(2, possible_to_save); } else { break; } } return {saved, time}; } pair<int, int> boundary(int bound_val, int time) { return {max(0, bound_val - time), time + max(0, min(bound_val - time, 1))}; } int solve() { int n; cin >> n; string s; cin >> s; vector<int> segments; vector<int> boundaries; int seg_len = 0; bool first_zero = (s[0] == '0'); for (char c : s) { if (c == '0') { seg_len += 1; } else { if (seg_len > 0) { if (first_zero && segments.empty()) { boundaries.push_back(seg_len); first_zero = false; } else { segments.push_back(seg_len); } seg_len = 0; } } } if (seg_len == n) return 0; if (seg_len > 0) boundaries.push_back(seg_len); sort(segments.begin(), segments.end(), greater<>()); sort(boundaries.begin(), boundaries.end(), greater<>()); int res = n; for (int i = -1; i < int(boundaries.size()); ++i) { int saved = 0, time = 0; for (int j = 0; j <= i; ++j) { auto b = boundary(boundaries[j], time); saved += b.first, time = b.second; } auto b = middle(segments, time); saved += b.first, time = b.second; for (int j = i + 1; j < boundaries.size(); ++j) { b = boundary(boundaries[j], time); saved += b.first, time = b.second; } res = min(res, n - saved); } return res; } int main() { boost; int t;cin >> t; for(int i = 0; i < t; ++i) { cout << solve() << '\n'; } return 0; } /** 5 4 1000 4 0100 4 0010 4 0001 4 1111 1 20 00001111001001111000 1 20 00011000000000001000 1 20 00101000101100100010 1 20 00000100000010000010 */ |
English