#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); } } |
English