#include <bits/stdc++.h>
#include "krazki.h"
#include "message.h"
using namespace std;
void solve(int n, int l, int r, bool byMyself) {
vector<long long> discDiameters;
for (int i = l; i <= r; i++) {
discDiameters.push_back(DiscDiameter(i));
}
vector<pair<long long, int>> descendingDiameters;
for (int i = 0; i < int(discDiameters.size()); i++) {
descendingDiameters.push_back({ discDiameters[i], i });
}
sort(descendingDiameters.begin(), descendingDiameters.end(), greater<pair<long long, int>>());
vector<int> naturalPositions(discDiameters.size(), n);
int nextDiskIdx = 0;
for (int i = 1; i <= n && nextDiskIdx < int(discDiameters.size()); i++) {
long long curHoleDiameter = HoleDiameter(i);
while (nextDiskIdx < int(discDiameters.size())
&& descendingDiameters[nextDiskIdx].first > curHoleDiameter) {
naturalPositions[descendingDiameters[nextDiskIdx].second] = i - 1;
nextDiskIdx++;
}
}
int previousLastPosition;
if (MyNodeId() == 0) {
previousLastPosition = n + 1;
} else {
Receive(MyNodeId() - 1);
previousLastPosition = GetInt(MyNodeId() - 1);
}
int actualLastPosition = previousLastPosition;
for (int naturalPosition: naturalPositions) {
actualLastPosition = min(naturalPosition, actualLastPosition - 1);
}
if (MyNodeId() + 1 < NumberOfNodes() && !byMyself) {
PutInt(MyNodeId() + 1, actualLastPosition);
Send(MyNodeId() + 1);
} else {
cout << max(0, actualLastPosition) << endl;
}
}
int main() {
int n = PipeHeight();
int m = NumberOfDiscs();
int discsPerInstance = m / NumberOfNodes();
if (discsPerInstance == 0) {
if (MyNodeId() == 0) {
solve(n, 1, m, true);
}
} else {
int l = MyNodeId() * discsPerInstance;
int r;
if (MyNodeId() == NumberOfNodes() - 1) {
r = m - 1;
} else {
r = (MyNodeId() + 1) * discsPerInstance - 1;
}
solve(n, l + 1, r + 1, false);
}
}
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 | #include <bits/stdc++.h> #include "krazki.h" #include "message.h" using namespace std; void solve(int n, int l, int r, bool byMyself) { vector<long long> discDiameters; for (int i = l; i <= r; i++) { discDiameters.push_back(DiscDiameter(i)); } vector<pair<long long, int>> descendingDiameters; for (int i = 0; i < int(discDiameters.size()); i++) { descendingDiameters.push_back({ discDiameters[i], i }); } sort(descendingDiameters.begin(), descendingDiameters.end(), greater<pair<long long, int>>()); vector<int> naturalPositions(discDiameters.size(), n); int nextDiskIdx = 0; for (int i = 1; i <= n && nextDiskIdx < int(discDiameters.size()); i++) { long long curHoleDiameter = HoleDiameter(i); while (nextDiskIdx < int(discDiameters.size()) && descendingDiameters[nextDiskIdx].first > curHoleDiameter) { naturalPositions[descendingDiameters[nextDiskIdx].second] = i - 1; nextDiskIdx++; } } int previousLastPosition; if (MyNodeId() == 0) { previousLastPosition = n + 1; } else { Receive(MyNodeId() - 1); previousLastPosition = GetInt(MyNodeId() - 1); } int actualLastPosition = previousLastPosition; for (int naturalPosition: naturalPositions) { actualLastPosition = min(naturalPosition, actualLastPosition - 1); } if (MyNodeId() + 1 < NumberOfNodes() && !byMyself) { PutInt(MyNodeId() + 1, actualLastPosition); Send(MyNodeId() + 1); } else { cout << max(0, actualLastPosition) << endl; } } int main() { int n = PipeHeight(); int m = NumberOfDiscs(); int discsPerInstance = m / NumberOfNodes(); if (discsPerInstance == 0) { if (MyNodeId() == 0) { solve(n, 1, m, true); } } else { int l = MyNodeId() * discsPerInstance; int r; if (MyNodeId() == NumberOfNodes() - 1) { r = m - 1; } else { r = (MyNodeId() + 1) * discsPerInstance - 1; } solve(n, l + 1, r + 1, false); } } |
English