#include "bits/stdc++.h" #include "krazki.h" #include "message.h" using namespace std; using LL = long long; int ExtendedPipeHeight() {return PipeHeight() + 1;} int ExtendedHoleDiameter(int n, int i) {return (i == n) ? 0 : HoleDiameter(i);} int main() { int n_buckets = 0; int number_of_nodes = NumberOfNodes(); int rect_ratio = min(4, number_of_nodes); while(rect_ratio * (n_buckets + 1) * (n_buckets + 1) <= number_of_nodes) ++n_buckets; number_of_nodes = rect_ratio * n_buckets * n_buckets; int my_node_id = MyNodeId(); if(my_node_id >= number_of_nodes) return EXIT_SUCCESS; int n = ExtendedPipeHeight(); int m = NumberOfDiscs(); int r = my_node_id % (rect_ratio * n_buckets); // [0, rect_ratio * n_buckets) int c = my_node_id / (rect_ratio * n_buckets); // [0, n_buckets) int i0 = 1 + (LL) r * n / (rect_ratio * n_buckets); int i1 = 1 + (LL) (r + 1) * n / (rect_ratio * n_buckets); vector<pair<LL, int>> v; v.reserve(i1-i0); for(int i = i0; i < i1; ++i){ LL r = ExtendedHoleDiameter(n, i); if(v.empty() || v.back().first > r){ v.emplace_back(r, i); } } int j0 = 1 + (LL) c * m / n_buckets; int j1 = 1 + (LL) (c + 1) * m / n_buckets; int best = n; int l = v.size(); for(int j = j0; j < j1; ++j) { int k = DiscDiameter(j); while(l > 0 && v[l-1].first < k) --l; if(l < (int) v.size()) { int i = v[l].second; int cand = max(0, i - (m - (j - 1))); best = min(best, cand); } } if (my_node_id != 0) { PutInt(0, best); Send(0); } else { for(int i = 1; i < number_of_nodes; ++i) { Receive(i); int i_best = GetInt(i); best = min(best, i_best); } printf("%d\n", max(best, 0)); } return EXIT_SUCCESS; }
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 | #include "bits/stdc++.h" #include "krazki.h" #include "message.h" using namespace std; using LL = long long; int ExtendedPipeHeight() {return PipeHeight() + 1;} int ExtendedHoleDiameter(int n, int i) {return (i == n) ? 0 : HoleDiameter(i);} int main() { int n_buckets = 0; int number_of_nodes = NumberOfNodes(); int rect_ratio = min(4, number_of_nodes); while(rect_ratio * (n_buckets + 1) * (n_buckets + 1) <= number_of_nodes) ++n_buckets; number_of_nodes = rect_ratio * n_buckets * n_buckets; int my_node_id = MyNodeId(); if(my_node_id >= number_of_nodes) return EXIT_SUCCESS; int n = ExtendedPipeHeight(); int m = NumberOfDiscs(); int r = my_node_id % (rect_ratio * n_buckets); // [0, rect_ratio * n_buckets) int c = my_node_id / (rect_ratio * n_buckets); // [0, n_buckets) int i0 = 1 + (LL) r * n / (rect_ratio * n_buckets); int i1 = 1 + (LL) (r + 1) * n / (rect_ratio * n_buckets); vector<pair<LL, int>> v; v.reserve(i1-i0); for(int i = i0; i < i1; ++i){ LL r = ExtendedHoleDiameter(n, i); if(v.empty() || v.back().first > r){ v.emplace_back(r, i); } } int j0 = 1 + (LL) c * m / n_buckets; int j1 = 1 + (LL) (c + 1) * m / n_buckets; int best = n; int l = v.size(); for(int j = j0; j < j1; ++j) { int k = DiscDiameter(j); while(l > 0 && v[l-1].first < k) --l; if(l < (int) v.size()) { int i = v[l].second; int cand = max(0, i - (m - (j - 1))); best = min(best, cand); } } if (my_node_id != 0) { PutInt(0, best); Send(0); } else { for(int i = 1; i < number_of_nodes; ++i) { Receive(i); int i_best = GetInt(i); best = min(best, i_best); } printf("%d\n", max(best, 0)); } return EXIT_SUCCESS; } |