#include <bits/stdc++.h>
using namespace std;
pair<vector<int>, vector<int>> parse(string& s) {
vector<int> zero_groups(1);
for (auto& c : s) {
if (c == '1') {
if (zero_groups.back() != 0)
zero_groups.push_back(0);
} else {
zero_groups.back()++;
}
}
if (zero_groups.back() == 0 && zero_groups.size() > 0) {
zero_groups.pop_back();
}
vector<int> single_sided;
if (s.back() == '0') {
single_sided.push_back(zero_groups.back());
zero_groups.pop_back();
}
if (zero_groups.size() > 0 && s.front() == '0') {
single_sided.push_back(zero_groups.front());
zero_groups.erase(zero_groups.begin());
}
sort(single_sided.begin(), single_sided.end()); // possibly slightly faster would be to use priority_queue in later phase
sort(zero_groups.begin(), zero_groups.end()); // because when there is many, most will not be used
return {single_sided, zero_groups};
}
int sol3(string& s) {
auto parsed = parse(s);
auto& single_sided = parsed.first;
auto& double_sided = parsed.second;
int step = 0;
int ans = 0;
while (single_sided.size() + double_sided.size() > 0) {
int single = 0;
if (single_sided.size() > 0) {
single = single_sided.back() - step;
}
int dbl = 0;
if (double_sided.size() > 0) {
dbl = double_sided.back() - 2 * step + 1;
}
if (max(single, dbl) <= 0)
break;
if (single > 0 && single + 3 >= dbl) {
auto x = single_sided.back();
single_sided.pop_back();
ans += x - step;
step += 1;
} else {
auto x = double_sided.back();
double_sided.pop_back();
if (x - 2 * step > 0) {
ans += 1;
step += 1;
int rest = x - 2 * step;
if (rest > 0) {
ans += rest;
step += 1;
}
}
}
}
return ans;
}
int main() {
// freopen("pan0.in", "r", stdin);
ios_base::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
string s;
cin >> s;
cout << s.size() - sol3(s) << "\n";
}
}
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 | #include <bits/stdc++.h> using namespace std; pair<vector<int>, vector<int>> parse(string& s) { vector<int> zero_groups(1); for (auto& c : s) { if (c == '1') { if (zero_groups.back() != 0) zero_groups.push_back(0); } else { zero_groups.back()++; } } if (zero_groups.back() == 0 && zero_groups.size() > 0) { zero_groups.pop_back(); } vector<int> single_sided; if (s.back() == '0') { single_sided.push_back(zero_groups.back()); zero_groups.pop_back(); } if (zero_groups.size() > 0 && s.front() == '0') { single_sided.push_back(zero_groups.front()); zero_groups.erase(zero_groups.begin()); } sort(single_sided.begin(), single_sided.end()); // possibly slightly faster would be to use priority_queue in later phase sort(zero_groups.begin(), zero_groups.end()); // because when there is many, most will not be used return {single_sided, zero_groups}; } int sol3(string& s) { auto parsed = parse(s); auto& single_sided = parsed.first; auto& double_sided = parsed.second; int step = 0; int ans = 0; while (single_sided.size() + double_sided.size() > 0) { int single = 0; if (single_sided.size() > 0) { single = single_sided.back() - step; } int dbl = 0; if (double_sided.size() > 0) { dbl = double_sided.back() - 2 * step + 1; } if (max(single, dbl) <= 0) break; if (single > 0 && single + 3 >= dbl) { auto x = single_sided.back(); single_sided.pop_back(); ans += x - step; step += 1; } else { auto x = double_sided.back(); double_sided.pop_back(); if (x - 2 * step > 0) { ans += 1; step += 1; int rest = x - 2 * step; if (rest > 0) { ans += rest; step += 1; } } } } return ans; } int main() { // freopen("pan0.in", "r", stdin); ios_base::sync_with_stdio(0); cin.tie(0); int t; cin >> t; while (t--) { int n; cin >> n; string s; cin >> s; cout << s.size() - sol3(s) << "\n"; } } |
English