#include <cstdio> #include <set> using namespace std; #define MAX 1000000 char b[MAX]; int best(int T, multiset<int> *w) { int v2 = -1, v1 = -1; if (!w[2].empty()) v2 = (*w[2].crbegin()) - 2*T; if (!w[1].empty()) v1 = (*w[1].crbegin()) - T; if (v2 >= 2*v1 && v2 >= 0) { w[2].erase(std::prev(w[2].end())); w[1].insert(v2 + T); } else if (v1 >= 0) { w[1].erase(std::prev(w[1].end())); return v1; } return 0; } void norm(int T, multiset<int> *w) { int v2 = -1, v1 = -1; while(!w[2].empty()) { v2 = (*w[2].begin()) - 2*T; if (v2 < 2) { w[2].erase(w[2].begin()); if(v2 == 1) { w[1].insert(v2 + T); } } else break; } while(!w[1].empty()) { v1 = (*w[1].begin()) - T; if (v1 < 1) { w[1].erase(w[1].begin()); } else break; } } void print(int T, multiset<int> *w) { printf("T = %d\n w[1] = ", T); for(auto v : w[1]) printf("%d ", v - T); printf("\n w[2] = "); for(auto v : w[2]) printf("%d ", v - 2*T); printf("\n"); } int main() { int t,n,f,l,d,r,T; scanf("%d", &t); while (t--) { scanf("%d %s", &n, b); for (f = 0; f < n && b[f] == '0'; f++); if (f == n) { printf("0\n"); continue; } for (l = n-1; l >=0 && b[l] == '0'; l--); multiset<int> w[3]; w[1].insert(f); w[1].insert(n-1-l); T = r = d = 0; while(f<=l) { if(b[f++]=='1') { w[2].insert(d); d = 0; } else d++; } norm(T, w); while(!(w[1].empty() && w[2].empty())) { // print(T, w); r += best(T++, w); // printf("r = %d\n", r); norm(T, w); } printf("%d\n", n-r); } }
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 | #include <cstdio> #include <set> using namespace std; #define MAX 1000000 char b[MAX]; int best(int T, multiset<int> *w) { int v2 = -1, v1 = -1; if (!w[2].empty()) v2 = (*w[2].crbegin()) - 2*T; if (!w[1].empty()) v1 = (*w[1].crbegin()) - T; if (v2 >= 2*v1 && v2 >= 0) { w[2].erase(std::prev(w[2].end())); w[1].insert(v2 + T); } else if (v1 >= 0) { w[1].erase(std::prev(w[1].end())); return v1; } return 0; } void norm(int T, multiset<int> *w) { int v2 = -1, v1 = -1; while(!w[2].empty()) { v2 = (*w[2].begin()) - 2*T; if (v2 < 2) { w[2].erase(w[2].begin()); if(v2 == 1) { w[1].insert(v2 + T); } } else break; } while(!w[1].empty()) { v1 = (*w[1].begin()) - T; if (v1 < 1) { w[1].erase(w[1].begin()); } else break; } } void print(int T, multiset<int> *w) { printf("T = %d\n w[1] = ", T); for(auto v : w[1]) printf("%d ", v - T); printf("\n w[2] = "); for(auto v : w[2]) printf("%d ", v - 2*T); printf("\n"); } int main() { int t,n,f,l,d,r,T; scanf("%d", &t); while (t--) { scanf("%d %s", &n, b); for (f = 0; f < n && b[f] == '0'; f++); if (f == n) { printf("0\n"); continue; } for (l = n-1; l >=0 && b[l] == '0'; l--); multiset<int> w[3]; w[1].insert(f); w[1].insert(n-1-l); T = r = d = 0; while(f<=l) { if(b[f++]=='1') { w[2].insert(d); d = 0; } else d++; } norm(T, w); while(!(w[1].empty() && w[2].empty())) { // print(T, w); r += best(T++, w); // printf("r = %d\n", r); norm(T, w); } printf("%d\n", n-r); } } |