#include "krazki.h" #include "message.h" #include <vector> #include <algorithm> #include <cstdio> int numOfNodes, numOfDiscs, pipeHeight, myNodeId; std::vector<long long> pipe; void end_zero(int result) { for (int i = 1; i <= numOfNodes; ++i) { PutLL(i, -1); Send(i); } printf("%d\n", result); exit(0); } int main() { numOfNodes = NumberOfNodes()-1; myNodeId = MyNodeId(); pipeHeight = PipeHeight(); numOfDiscs = NumberOfDiscs(); if (myNodeId != 0) { int beg, lim, myPipeHeight; int l = pipeHeight/numOfNodes, r = pipeHeight%numOfNodes; beg = std::min(r, myNodeId-1)+(myNodeId-1)*l+1; if (myNodeId <= r) l++; lim = beg + l; beg = std::min(beg, pipeHeight+1); lim = std::min(lim, pipeHeight+1); // fprintf(stderr, "beg=%d lim=%d l=%d r=%d\n", beg, lim, l, r); for (int i = beg; i<lim; ++i) pipe.push_back(HoleDiameter(i)); myPipeHeight = pipe.size(); for (int i = 1; i<myPipeHeight; ++i) pipe[i] = std::min(pipe[i], pipe[i-1]); long long x = 1LL<<62LL; if (myNodeId != 1) { Receive(myNodeId-1); x = GetLL(myNodeId-1); if (myPipeHeight > 0) pipe[myPipeHeight-1] = std::min(pipe[myPipeHeight-1], x); } if (myNodeId != numOfNodes) { if (myPipeHeight > 0) PutLL(myNodeId+1, pipe[myPipeHeight-1]); else PutLL(myNodeId+1, 0); Send(myNodeId+1); } for (int i = 0; i < myPipeHeight; ++i) pipe[i] = std::min(pipe[i], x); Receive(0); long long query = GetLL(0), newIndex; int result; while (query != -1) { result = 0; for (int i = 0; i < myPipeHeight; ++i) { newIndex = numOfDiscs - ((i + beg) - query); // if (query == 9) // fprintf(stderr, "query = %lld current_pos = %lld newIndex=%lld\n", query, beg+i, newIndex); if (newIndex > 0 && newIndex <= numOfDiscs) { // if (query == 9) // fprintf(stderr, "current_pos=%d i=%d newIndex=%lld pipe[i]=%lld DiscDiameter(newIndex)=%lld\n", i+beg, i, newIndex, pipe[i], DiscDiameter(newIndex)); if (pipe[i] < DiscDiameter(newIndex)) result = 1; } } PutInt(0, result); // if (query == 9) // fprintf(stderr, "result = %d\n", result); Send(0); Receive(0); query = GetLL(0); } exit(0); } else { long long k = pipeHeight-numOfDiscs+2, p = 0, m; bool result; if (numOfDiscs>pipeHeight) end_zero(0); while (k-p>1) { result = false; m = (p+k)/2; for (int i = 1; i <= numOfNodes; ++i) { PutLL(i, m); Send(i); Receive(i); result |= bool(GetInt(i)); } // fprintf(stderr, "p=%lld k=%lld m=%d result=%d\n", p, k, m, result); if (result) k = m; else p = m; } end_zero(p); } }
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 | #include "krazki.h" #include "message.h" #include <vector> #include <algorithm> #include <cstdio> int numOfNodes, numOfDiscs, pipeHeight, myNodeId; std::vector<long long> pipe; void end_zero(int result) { for (int i = 1; i <= numOfNodes; ++i) { PutLL(i, -1); Send(i); } printf("%d\n", result); exit(0); } int main() { numOfNodes = NumberOfNodes()-1; myNodeId = MyNodeId(); pipeHeight = PipeHeight(); numOfDiscs = NumberOfDiscs(); if (myNodeId != 0) { int beg, lim, myPipeHeight; int l = pipeHeight/numOfNodes, r = pipeHeight%numOfNodes; beg = std::min(r, myNodeId-1)+(myNodeId-1)*l+1; if (myNodeId <= r) l++; lim = beg + l; beg = std::min(beg, pipeHeight+1); lim = std::min(lim, pipeHeight+1); // fprintf(stderr, "beg=%d lim=%d l=%d r=%d\n", beg, lim, l, r); for (int i = beg; i<lim; ++i) pipe.push_back(HoleDiameter(i)); myPipeHeight = pipe.size(); for (int i = 1; i<myPipeHeight; ++i) pipe[i] = std::min(pipe[i], pipe[i-1]); long long x = 1LL<<62LL; if (myNodeId != 1) { Receive(myNodeId-1); x = GetLL(myNodeId-1); if (myPipeHeight > 0) pipe[myPipeHeight-1] = std::min(pipe[myPipeHeight-1], x); } if (myNodeId != numOfNodes) { if (myPipeHeight > 0) PutLL(myNodeId+1, pipe[myPipeHeight-1]); else PutLL(myNodeId+1, 0); Send(myNodeId+1); } for (int i = 0; i < myPipeHeight; ++i) pipe[i] = std::min(pipe[i], x); Receive(0); long long query = GetLL(0), newIndex; int result; while (query != -1) { result = 0; for (int i = 0; i < myPipeHeight; ++i) { newIndex = numOfDiscs - ((i + beg) - query); // if (query == 9) // fprintf(stderr, "query = %lld current_pos = %lld newIndex=%lld\n", query, beg+i, newIndex); if (newIndex > 0 && newIndex <= numOfDiscs) { // if (query == 9) // fprintf(stderr, "current_pos=%d i=%d newIndex=%lld pipe[i]=%lld DiscDiameter(newIndex)=%lld\n", i+beg, i, newIndex, pipe[i], DiscDiameter(newIndex)); if (pipe[i] < DiscDiameter(newIndex)) result = 1; } } PutInt(0, result); // if (query == 9) // fprintf(stderr, "result = %d\n", result); Send(0); Receive(0); query = GetLL(0); } exit(0); } else { long long k = pipeHeight-numOfDiscs+2, p = 0, m; bool result; if (numOfDiscs>pipeHeight) end_zero(0); while (k-p>1) { result = false; m = (p+k)/2; for (int i = 1; i <= numOfNodes; ++i) { PutLL(i, m); Send(i); Receive(i); result |= bool(GetInt(i)); } // fprintf(stderr, "p=%lld k=%lld m=%d result=%d\n", p, k, m, result); if (result) k = m; else p = m; } end_zero(p); } } |