// Created by Michal Kowalski on 07/12/2021. // #include <iostream> #include <map> #include <unordered_map> #include <vector> #include <algorithm> int N; inline int takefrom1(std::vector<std::pair<int, int>> & V1, int day) { // take only one sided group int len = V1[0].first - (day - 1); --V1[0].second; if (V1[0].second == 0) { V1.erase(V1.begin()); } return len; } inline int takefrom2(std::vector<std::pair<int, int>> & V1, std::vector<std::pair<int, int>> & V2,int day) { int len = V2[0].first - (day - 1) * 2; int count = V2[0].second; --count; --len; if (count == 0) { V2.erase(V2.begin()); } else { V2[0].second = count; } if (len > 0) { V1.insert(V1.begin(), {len, 1}); } return 1; } int main(int argc, const char * argv[]) { scanf("%d",&N); for (int i=0;i<N;++i) { int K; scanf("%d",&K); char S[K+1]; scanf("%s",S); // maps std::unordered_map<int, int> M2; std::unordered_map<int, int> M1; // read from input int lastIndex = -1; for (int j=0;j<K;++j) { if (S[j] == '1') { if (lastIndex == -1) { if (j>0) { int len = j; //std::cout << "x" <<std::string(len, '0') << std::endl; if (M1.find(len) != M1.end()) { M1[len] = M1[len] + 1; } else { M1[len] = 1; } } } else { if (j - lastIndex > 1) { int len = j-lastIndex-1; //std::cout << std::string(len, '0') << std::endl; if (M2.find(len) != M2.end()) { M2[len] = M2[len] + 1; } else { M2[len] = 1; } } } lastIndex = j; } } // no infection go to next test case if (lastIndex == -1) { printf("0\n"); continue; } if (lastIndex < K && K-lastIndex > 1) { int len = K-lastIndex-1; //std::cout << std::string(len, '0') << "x" << std::endl; if (M1.find(len) != M1.end()) { M1[len] = M1[len] + 1; } else { M1[len] = 1; } } // for both sided groups std::vector<std::pair<int, int>> V2; V2.reserve(M2.size()); for (const auto &[len, count] : M2) { //std::cout << count << " x " << len << "\n"; V2.push_back({len, count}); } std::sort(V2.begin(), V2.end(), std::greater<std::pair<int, int>>()); // for one sided groups std::vector<std::pair<int, int>> V1; V1.reserve(M1.size()); for (const auto &[len, count] : M1) { //std::cout << count << " x " << len << "\n"; V1.push_back({len, count}); } std::sort(V1.begin(), V1.end(), std::greater<std::pair<int, int>>()); int day = 1; int vacc = 0; while (!V1.empty() || !V2.empty()) { if (V2.empty()) { vacc += takefrom1(V1, day); } else if (V1.empty()) { vacc += takefrom2(V1, V2, day); } else { // items in both queues int len1 = V1[0].first - (day - 1); int len2 = V2[0].first - (day - 1) * 2; if (len2 - 2 > len1 - 1) { vacc += takefrom2(V1, V2, day); } else { vacc += takefrom1(V1, day); } } //make infections if ((V2.rbegin() != V2.rend()) && (*V2.rbegin()).first <= day*2) V2.pop_back(); if ((V2.rbegin() != V2.rend()) && (*V2.rbegin()).first <= day*2) V2.pop_back(); std::sort(V1.begin(), V1.end(), std::greater<std::pair<int, int>>()); while(!V1.empty() && (*V1.rbegin()).first <= day) V1.pop_back(); ++day; } printf("%d\n",K-vacc); } 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 139 140 | // Created by Michal Kowalski on 07/12/2021. // #include <iostream> #include <map> #include <unordered_map> #include <vector> #include <algorithm> int N; inline int takefrom1(std::vector<std::pair<int, int>> & V1, int day) { // take only one sided group int len = V1[0].first - (day - 1); --V1[0].second; if (V1[0].second == 0) { V1.erase(V1.begin()); } return len; } inline int takefrom2(std::vector<std::pair<int, int>> & V1, std::vector<std::pair<int, int>> & V2,int day) { int len = V2[0].first - (day - 1) * 2; int count = V2[0].second; --count; --len; if (count == 0) { V2.erase(V2.begin()); } else { V2[0].second = count; } if (len > 0) { V1.insert(V1.begin(), {len, 1}); } return 1; } int main(int argc, const char * argv[]) { scanf("%d",&N); for (int i=0;i<N;++i) { int K; scanf("%d",&K); char S[K+1]; scanf("%s",S); // maps std::unordered_map<int, int> M2; std::unordered_map<int, int> M1; // read from input int lastIndex = -1; for (int j=0;j<K;++j) { if (S[j] == '1') { if (lastIndex == -1) { if (j>0) { int len = j; //std::cout << "x" <<std::string(len, '0') << std::endl; if (M1.find(len) != M1.end()) { M1[len] = M1[len] + 1; } else { M1[len] = 1; } } } else { if (j - lastIndex > 1) { int len = j-lastIndex-1; //std::cout << std::string(len, '0') << std::endl; if (M2.find(len) != M2.end()) { M2[len] = M2[len] + 1; } else { M2[len] = 1; } } } lastIndex = j; } } // no infection go to next test case if (lastIndex == -1) { printf("0\n"); continue; } if (lastIndex < K && K-lastIndex > 1) { int len = K-lastIndex-1; //std::cout << std::string(len, '0') << "x" << std::endl; if (M1.find(len) != M1.end()) { M1[len] = M1[len] + 1; } else { M1[len] = 1; } } // for both sided groups std::vector<std::pair<int, int>> V2; V2.reserve(M2.size()); for (const auto &[len, count] : M2) { //std::cout << count << " x " << len << "\n"; V2.push_back({len, count}); } std::sort(V2.begin(), V2.end(), std::greater<std::pair<int, int>>()); // for one sided groups std::vector<std::pair<int, int>> V1; V1.reserve(M1.size()); for (const auto &[len, count] : M1) { //std::cout << count << " x " << len << "\n"; V1.push_back({len, count}); } std::sort(V1.begin(), V1.end(), std::greater<std::pair<int, int>>()); int day = 1; int vacc = 0; while (!V1.empty() || !V2.empty()) { if (V2.empty()) { vacc += takefrom1(V1, day); } else if (V1.empty()) { vacc += takefrom2(V1, V2, day); } else { // items in both queues int len1 = V1[0].first - (day - 1); int len2 = V2[0].first - (day - 1) * 2; if (len2 - 2 > len1 - 1) { vacc += takefrom2(V1, V2, day); } else { vacc += takefrom1(V1, day); } } //make infections if ((V2.rbegin() != V2.rend()) && (*V2.rbegin()).first <= day*2) V2.pop_back(); if ((V2.rbegin() != V2.rend()) && (*V2.rbegin()).first <= day*2) V2.pop_back(); std::sort(V1.begin(), V1.end(), std::greater<std::pair<int, int>>()); while(!V1.empty() && (*V1.rbegin()).first <= day) V1.pop_back(); ++day; } printf("%d\n",K-vacc); } return 0; } |