#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); } } |
English