#include <bits/stdc++.h> const int MAXN = 100005; char t[MAXN]; int buckets[MAXN]; void answer(int ans) { printf("%d\n", ans); } int get_score(const std::vector<int> &v, int left, int right, int take_left, int take_right) { int iter = 0; int score = 0; if (take_left) { score += left; iter++; } if (take_right) { score += std::max(0, right-iter); iter++; } for (int i=v.size()-1; i>=0; i--) { // printf("ccc %d %d, %d %d\n", i, v[i], iter, score); if (v[i] <= 2*iter) return score; if (v[i] == 2*iter + 1) return score + 1; score += v[i] - 2*iter - 1; iter += 2; } return score; } void solve() { int n; scanf("%d", &n); scanf("%s", t); int left = 0; for (int i=0; i<n; i++) { if (t[i] == '0') left++; else break; } if (left == n) return answer(0); int right = 0; for (int i=n-1; i>=0; i--) { if (t[i] == '0') right++; else break; } int begin_idx = 0; std::vector<int> v; for (int i=left; i<n-1; i++) { if (t[i] == '1' && t[i+1] == '0') begin_idx = i; if (t[i] == '0' && t[i+1] == '1') { // found i-begin_idx buckets[i-begin_idx]++; } } for (int i=1; i<=n; i++) { for (int x=0; x<buckets[i]; x++) v.push_back(i); buckets[i] = 0; } // printf("left %d right %d\n", left, right); int sc = 0; if (right > left) std::swap(right, left); // now left is bigger for (int take_left=0; take_left<2; take_left++) { for (int take_right=0; take_right<=take_left; take_right++) { if (take_left && left == 0) continue; if (take_right && right == 0) continue; int tmp = get_score(v, left, right, take_left, take_right); // printf("aaa %d %d %d\n", take_left, take_right, tmp); sc = std::max(sc, tmp); } } answer(n-sc); } int main() { int T; scanf("%d", &T); while (T--) { solve(); } return 0; }
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 | #include <bits/stdc++.h> const int MAXN = 100005; char t[MAXN]; int buckets[MAXN]; void answer(int ans) { printf("%d\n", ans); } int get_score(const std::vector<int> &v, int left, int right, int take_left, int take_right) { int iter = 0; int score = 0; if (take_left) { score += left; iter++; } if (take_right) { score += std::max(0, right-iter); iter++; } for (int i=v.size()-1; i>=0; i--) { // printf("ccc %d %d, %d %d\n", i, v[i], iter, score); if (v[i] <= 2*iter) return score; if (v[i] == 2*iter + 1) return score + 1; score += v[i] - 2*iter - 1; iter += 2; } return score; } void solve() { int n; scanf("%d", &n); scanf("%s", t); int left = 0; for (int i=0; i<n; i++) { if (t[i] == '0') left++; else break; } if (left == n) return answer(0); int right = 0; for (int i=n-1; i>=0; i--) { if (t[i] == '0') right++; else break; } int begin_idx = 0; std::vector<int> v; for (int i=left; i<n-1; i++) { if (t[i] == '1' && t[i+1] == '0') begin_idx = i; if (t[i] == '0' && t[i+1] == '1') { // found i-begin_idx buckets[i-begin_idx]++; } } for (int i=1; i<=n; i++) { for (int x=0; x<buckets[i]; x++) v.push_back(i); buckets[i] = 0; } // printf("left %d right %d\n", left, right); int sc = 0; if (right > left) std::swap(right, left); // now left is bigger for (int take_left=0; take_left<2; take_left++) { for (int take_right=0; take_right<=take_left; take_right++) { if (take_left && left == 0) continue; if (take_right && right == 0) continue; int tmp = get_score(v, left, right, take_left, take_right); // printf("aaa %d %d %d\n", take_left, take_right, tmp); sc = std::max(sc, tmp); } } answer(n-sc); } int main() { int T; scanf("%d", &T); while (T--) { solve(); } return 0; } |