#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"; } } |