#include <iostream> #include <map> #include <vector> using namespace std; #define debug if(false) cout class Calc { int n; int left; int right; int* counter; int sick; int safe; int step; public: Calc() { counter=(int*)malloc(sizeof(int)*100002); } void reset(int n) { this->n=n; for(int i=0;i<=n;++i) counter[i]=0; } /** * Zliczamy wszystkie puste przestrzenie, czyli ciągi 0 */ void processInput(string& src) { left=0; right=0; sick=0; int last=-1; for(int i=0;i<n;++i) { if(src[i]=='1') { ++sick; int dist=(i-last)-1; if(last==-1) left=dist; else if(dist>0) counter[dist]++; last=i; } } if(last+1<n) right=n-last-1; debug<<"Left space: "<<left<<", right space: "<<right<<endl; for(int i=0;i<n;++i) { if(counter[i]>0) { debug<<"Space: "<<i<<"="<<counter[i]<<endl; } } } bool checkBorder(bool last) { if(left-step> (last?0:1)) { debug<<"Left left "<<(left-step)<<" at step: "<<step<<endl; safe+=left-step; left=0; ++step; return true; } if(right-step>(last?0:1)) { debug<<"Right left "<<(right-step)<<" at step: "<<step<<endl; safe+=right-step; right=0; ++step; return true; } return false; } int calc() { if(sick==0) return 0; // przypadek samych 0 /** Liczba zabezpieczonych miast */ safe=0; /** krok epidemii */ step=0; // W każdym kroku każda pusta przestrzeń (poza bocznymi) zmniejsza się o 2 pola (miasta). // Idziemy od największych, ocalimy najwięcej miast int i=n; while(i>0) { int l=i-(step*2); if(l<0) break; int sp=counter[i]; if(sp==0) { // brak przestrzeni --i; continue; } debug<<"It: "<<i<<", Step: "<<step<<" Safe: "<<safe<<" Items: "<<sp<<" Left: "<<l<<endl; if(checkBorder(false)) continue; ++step; // będzie kolejny krok epidemii --counter[i]; // przestrzeń zostanie "uratowana" if(l==1) { safe++; // ostatnie miasto } else { // od razu z 2 stron safe+=l-1; ++step; // więc dwa kroki } } checkBorder(true); checkBorder(true); debug<<"Saved: "<<safe<<endl; return n-safe; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); Calc c; int tests; cin>>tests; for(int test=0;test<tests;++test) { int n; cin>>n; string data; getline(cin, data); getline(cin, data); debug<<"Test: "<<test<<endl; c.reset(n); c.processInput(data); int res=c.calc(); cout<<res<<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 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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | #include <iostream> #include <map> #include <vector> using namespace std; #define debug if(false) cout class Calc { int n; int left; int right; int* counter; int sick; int safe; int step; public: Calc() { counter=(int*)malloc(sizeof(int)*100002); } void reset(int n) { this->n=n; for(int i=0;i<=n;++i) counter[i]=0; } /** * Zliczamy wszystkie puste przestrzenie, czyli ciągi 0 */ void processInput(string& src) { left=0; right=0; sick=0; int last=-1; for(int i=0;i<n;++i) { if(src[i]=='1') { ++sick; int dist=(i-last)-1; if(last==-1) left=dist; else if(dist>0) counter[dist]++; last=i; } } if(last+1<n) right=n-last-1; debug<<"Left space: "<<left<<", right space: "<<right<<endl; for(int i=0;i<n;++i) { if(counter[i]>0) { debug<<"Space: "<<i<<"="<<counter[i]<<endl; } } } bool checkBorder(bool last) { if(left-step> (last?0:1)) { debug<<"Left left "<<(left-step)<<" at step: "<<step<<endl; safe+=left-step; left=0; ++step; return true; } if(right-step>(last?0:1)) { debug<<"Right left "<<(right-step)<<" at step: "<<step<<endl; safe+=right-step; right=0; ++step; return true; } return false; } int calc() { if(sick==0) return 0; // przypadek samych 0 /** Liczba zabezpieczonych miast */ safe=0; /** krok epidemii */ step=0; // W każdym kroku każda pusta przestrzeń (poza bocznymi) zmniejsza się o 2 pola (miasta). // Idziemy od największych, ocalimy najwięcej miast int i=n; while(i>0) { int l=i-(step*2); if(l<0) break; int sp=counter[i]; if(sp==0) { // brak przestrzeni --i; continue; } debug<<"It: "<<i<<", Step: "<<step<<" Safe: "<<safe<<" Items: "<<sp<<" Left: "<<l<<endl; if(checkBorder(false)) continue; ++step; // będzie kolejny krok epidemii --counter[i]; // przestrzeń zostanie "uratowana" if(l==1) { safe++; // ostatnie miasto } else { // od razu z 2 stron safe+=l-1; ++step; // więc dwa kroki } } checkBorder(true); checkBorder(true); debug<<"Saved: "<<safe<<endl; return n-safe; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); Calc c; int tests; cin>>tests; for(int test=0;test<tests;++test) { int n; cin>>n; string data; getline(cin, data); getline(cin, data); debug<<"Test: "<<test<<endl; c.reset(n); c.processInput(data); int res=c.calc(); cout<<res<<endl; } return 0; } |