// PA2015, runda 4, Poszukiwania
// Andrzej Pezarski
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include "message.h"
#include "krazki.h"
using namespace std;
int main() {
int N=PipeHeight();
int M=NumberOfDiscs();
int nodes=NumberOfNodes();
int my_id=MyNodeId();
nodes=min(min(nodes, N), M);
if (my_id>=nodes) return 0;
long long first1 = min(N, (N / nodes) * my_id + min(my_id, N % nodes));
long long last1 = min(N, (N / nodes) * (my_id +1) + min(my_id+1, N % nodes));
long long myN = last1-first1;
long long first2 = min(M, (M / nodes) * my_id + min(my_id, M % nodes));
long long last2 = min(M, (M / nodes) * (my_id +1) + min(my_id+1, M % nodes));
long long myM = last2-first2;
long long myMinHole=1000000000000000000LL;
for (int i=first1; i<last1; i++) {
myMinHole=min(myMinHole, HoleDiameter(N-i));
}
for (int i=0; i<nodes; i++) {
PutLL(i, first1);
PutLL(i, myMinHole);
Send(i);
}
vector<pair<long long, long long> > V(nodes);
for (int i=0; i<nodes; i++) {
Receive(i);
long long x=GetLL(i);
long long y=GetLL(i);
V[i]=make_pair(x, y);
}
for (int i=nodes-2; i>=0; i--) {
V[i].second=min(V[i].second,V[i+1].second);
}
V.push_back(make_pair(last1, 1000000000000000000LL));
long long myMaxDisc=0LL;
for (int i=first2; i<last2; i++) {
myMaxDisc=max(myMaxDisc, DiscDiameter(i+1));
}
long long hIdx=last1;
long long hD=0LL;
for(auto x:V) {
if (x.second>=myMaxDisc) {
hIdx=x.first;
hD=x.second;
break;
}
}
vector<long long> A, B;
for (int i=1; i<=myM+myN && hIdx>0; i++) {
hD = min(hD ,HoleDiameter(N-(--hIdx)));
A.push_back(hD);
}
long long dD=0LL;
for (int i=first2; i<last2; i++) {
dD = max(dD, DiscDiameter(i+1));
B.push_back(dD);
}
reverse(B.begin(), B.end());
while (A.size() && B.size()) {
if (A.back()>=B.back()) {
B.pop_back();
}
A.pop_back();
hIdx++;
}
hIdx+=B.size();
PutLL(0, hIdx);
Send(0);
if (my_id == 0) {
long long res = 0LL;
for (int i=0; i<nodes; i++){
Receive(i);
res=max(res, GetLL(i));
printf("%lld", max(0LL, N-res+1));
}
}
return 0;
}
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 | // PA2015, runda 4, Poszukiwania // Andrzej Pezarski #include <cstdio> #include <cstdlib> #include <vector> #include <set> #include <map> #include <algorithm> #include "message.h" #include "krazki.h" using namespace std; int main() { int N=PipeHeight(); int M=NumberOfDiscs(); int nodes=NumberOfNodes(); int my_id=MyNodeId(); nodes=min(min(nodes, N), M); if (my_id>=nodes) return 0; long long first1 = min(N, (N / nodes) * my_id + min(my_id, N % nodes)); long long last1 = min(N, (N / nodes) * (my_id +1) + min(my_id+1, N % nodes)); long long myN = last1-first1; long long first2 = min(M, (M / nodes) * my_id + min(my_id, M % nodes)); long long last2 = min(M, (M / nodes) * (my_id +1) + min(my_id+1, M % nodes)); long long myM = last2-first2; long long myMinHole=1000000000000000000LL; for (int i=first1; i<last1; i++) { myMinHole=min(myMinHole, HoleDiameter(N-i)); } for (int i=0; i<nodes; i++) { PutLL(i, first1); PutLL(i, myMinHole); Send(i); } vector<pair<long long, long long> > V(nodes); for (int i=0; i<nodes; i++) { Receive(i); long long x=GetLL(i); long long y=GetLL(i); V[i]=make_pair(x, y); } for (int i=nodes-2; i>=0; i--) { V[i].second=min(V[i].second,V[i+1].second); } V.push_back(make_pair(last1, 1000000000000000000LL)); long long myMaxDisc=0LL; for (int i=first2; i<last2; i++) { myMaxDisc=max(myMaxDisc, DiscDiameter(i+1)); } long long hIdx=last1; long long hD=0LL; for(auto x:V) { if (x.second>=myMaxDisc) { hIdx=x.first; hD=x.second; break; } } vector<long long> A, B; for (int i=1; i<=myM+myN && hIdx>0; i++) { hD = min(hD ,HoleDiameter(N-(--hIdx))); A.push_back(hD); } long long dD=0LL; for (int i=first2; i<last2; i++) { dD = max(dD, DiscDiameter(i+1)); B.push_back(dD); } reverse(B.begin(), B.end()); while (A.size() && B.size()) { if (A.back()>=B.back()) { B.pop_back(); } A.pop_back(); hIdx++; } hIdx+=B.size(); PutLL(0, hIdx); Send(0); if (my_id == 0) { long long res = 0LL; for (int i=0; i<nodes; i++){ Receive(i); res=max(res, GetLL(i)); printf("%lld", max(0LL, N-res+1)); } } return 0; } |
English