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
#include <cstdlib>
#include <iostream>
#include <algorithm>

#include "krazki.h"
#include "message.h"

int findDepth(long long diam, int to) {
    for (int i = 1; i <= to; ++i) {
        if (diam > HoleDiameter(i)) {
            return i - 1;
        }
    }
    return to;
}

int main() {
        int myId = MyNodeId();
        int nodesCount = NumberOfNodes();
        int discsCount = NumberOfDiscs();
        int step;
        
        if (discsCount < nodesCount) {
            if (myId != 0) {
                return 0;
            }
            nodesCount = 1;
            step = discsCount;
        } else {
            step = discsCount / (double)nodesCount + 0.5;
        }

        int from = myId * step + 1;
        int to = myId == (nodesCount - 1) ? discsCount + 1 : from + step;

        int lastDepth = PipeHeight() + 1;
        long long maxDiam = 0;

        for (int i = from; i < to; ++i) {
            long long currentDiam = DiscDiameter(i);
            if (currentDiam <= maxDiam) {
                --lastDepth; 
            } else {
                lastDepth = findDepth(currentDiam, lastDepth);
                maxDiam = currentDiam;
            }
            if (lastDepth <= 0) {
                break;
            } 
        }
        if (myId != 0) {
           PutInt(0, lastDepth);
           Send(0);
        }

        if (myId == 0) {
            for (int i = 1; i<nodesCount; ++i) {
                if (lastDepth <= 0) {
                    break;
                }
                Receive(i);
                int nextLastDepth = GetInt(i);
                int chunkSize = i < (nodesCount - 1) ? step : discsCount - step * (nodesCount -1);
                lastDepth = std::min(lastDepth - chunkSize, nextLastDepth);
            }
            std::cout << std::max(lastDepth, 0);
        }
    return 0;
}