#include <iostream> // std::cout
#include <algorithm> // std::sort
#include <vector> // std::vector
#include <set>
#include <cmath>
#include <string>
#include <map>
#include <cassert>
#include <functional>
#include <tuple>
#define PBI pair<bool,int>
#define MAXN 1000001
#define DEBUG 0
using namespace std;
int n,z;
string c;
bool cmp_healthies(PBI a, PBI b){
int a_deadline = (a.first)? a.second : (a.second / 2) + (a.second & 1);
int b_deadline = (b.first)? b.second : (b.second / 2) + (b.second & 1);
if (a_deadline == b_deadline) {
if (a.first == b.first){ //when both outside / inside
return a.second > b.second; // prioritize longer healthies
}
return a.first > b.first; // prioritize healthies outside
}
return a_deadline > b_deadline; // prioritize higher time to death of healthies
}
int get_cities_saved_after_round (PBI healthie, int plague_round){
// for outside healthies we lose 1 city every round
if (healthie.first) return healthie.second - plague_round;
int res = healthie.second - (2 * plague_round);
if (res > 1) res --;
return res;
}
int solve(int &n, string &c){
if (DEBUG) cout << "\n\n\n**************************\n" << "SOLVE " << n << ' ' << c << endl;
vector<PBI> healthies;
for (int i=0; i<n; i++) {
int start=i, zeros_length=0;
for (; i<n && c[i] == '0'; zeros_length++, i++);
if (zeros_length){
healthies.push_back( PBI((start == 0 || i == n), zeros_length) );
}
}
sort(healthies.begin(), healthies.end(), cmp_healthies);
if (DEBUG) {
cout << "Healthies: " << endl;
for (auto h: healthies){
cout << " (" << h.first << ") from length " << h.second << endl;
}
}
if (DEBUG) cout << "Algorithm: " << endl;
int plague_round=0, cities_saved=0;
for(PBI h: healthies) {
cities_saved += max( get_cities_saved_after_round(h, plague_round), 0);
if (DEBUG) cout << " [" << plague_round << "] saving no cities: " << get_cities_saved_after_round(h, plague_round) << endl;
plague_round += 1 + (!h.first); // if we are inside we lose 2 rounds to vaccinate cities on both sides
}
return n - cities_saved;
}
int main() {
scanf("%d", &z);
while (z--){
scanf("%d\n", &n);
getline(cin, c);
cout << solve(n,c) << endl;
}
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 | #include <iostream> // std::cout #include <algorithm> // std::sort #include <vector> // std::vector #include <set> #include <cmath> #include <string> #include <map> #include <cassert> #include <functional> #include <tuple> #define PBI pair<bool,int> #define MAXN 1000001 #define DEBUG 0 using namespace std; int n,z; string c; bool cmp_healthies(PBI a, PBI b){ int a_deadline = (a.first)? a.second : (a.second / 2) + (a.second & 1); int b_deadline = (b.first)? b.second : (b.second / 2) + (b.second & 1); if (a_deadline == b_deadline) { if (a.first == b.first){ //when both outside / inside return a.second > b.second; // prioritize longer healthies } return a.first > b.first; // prioritize healthies outside } return a_deadline > b_deadline; // prioritize higher time to death of healthies } int get_cities_saved_after_round (PBI healthie, int plague_round){ // for outside healthies we lose 1 city every round if (healthie.first) return healthie.second - plague_round; int res = healthie.second - (2 * plague_round); if (res > 1) res --; return res; } int solve(int &n, string &c){ if (DEBUG) cout << "\n\n\n**************************\n" << "SOLVE " << n << ' ' << c << endl; vector<PBI> healthies; for (int i=0; i<n; i++) { int start=i, zeros_length=0; for (; i<n && c[i] == '0'; zeros_length++, i++); if (zeros_length){ healthies.push_back( PBI((start == 0 || i == n), zeros_length) ); } } sort(healthies.begin(), healthies.end(), cmp_healthies); if (DEBUG) { cout << "Healthies: " << endl; for (auto h: healthies){ cout << " (" << h.first << ") from length " << h.second << endl; } } if (DEBUG) cout << "Algorithm: " << endl; int plague_round=0, cities_saved=0; for(PBI h: healthies) { cities_saved += max( get_cities_saved_after_round(h, plague_round), 0); if (DEBUG) cout << " [" << plague_round << "] saving no cities: " << get_cities_saved_after_round(h, plague_round) << endl; plague_round += 1 + (!h.first); // if we are inside we lose 2 rounds to vaccinate cities on both sides } return n - cities_saved; } int main() { scanf("%d", &z); while (z--){ scanf("%d\n", &n); getline(cin, c); cout << solve(n,c) << endl; } return 0; } |
English