#include "message.h" #include "krazki.h" #include <vector> #include <iostream> using namespace std; typedef long long int LL; LL depth; LL disks; int instances ; LL findBlocker(LL upper, LL lower) { if (depth < disks) return 0; if (lower == 0) return 0; // -- upper (1) inclusive LL h = lower-upper+1; // ---- vector<LL> pipeDiamater(h); // -- lower (3) inclusive // -- // - total depth (5) pipeDiamater[0]=HoleDiameter(upper); for(LL i=1; i < h; i++) { pipeDiamater[i]=HoleDiameter(i+upper); if (pipeDiamater[i] > pipeDiamater[i-1]) pipeDiamater[i]=pipeDiamater[i-1]; // lejek \ / pipeline[0] } // \ / pipeline[1] LL filled = 0; LL minSize = pipeDiamater[h-1]; LL shift = 0; LL stacked = 0; for(LL i=1; i<=disks; i++) { LL size = DiscDiameter(i); //cout << "disk: " << i << " size: " << size << " " << shift << " " << stacked << " min size: " << minSize << endl; if (size <= minSize) // przechodzi { if (stacked) minSize = pipeDiamater[--stacked-1]; continue; } else // nie przechodzi - szukam, gdzie sie zatrzyma { LL blockIndex = (stacked != 0 ? stacked : h-1); while ((blockIndex>=0) && (size > pipeDiamater[blockIndex])) blockIndex-- ; shift = depth - upper - blockIndex - i + 1; // depth - upper <- tyle powinno wejsc dyskow, weszlo juz i, teraz zacielo sie na wysokosci blockIndex if ( blockIndex > 0 ) { minSize = pipeDiamater[blockIndex-1]; // pierwsze wolne miejsce stacked = blockIndex; // miejsce gdzie zablokowal sie ostatni krazek } } if (stacked == 1) break; if (shift >= depth - i + 1) break; // wystaje gora if (shift + upper + i - 2 >= depth) break; // opieramy sie o dno } return shift; } int main() { instances = NumberOfNodes(); depth = PipeHeight(); disks = NumberOfDiscs(); LL h = depth/(instances - 1); int myinstance = MyNodeId(); LL lower = myinstance * h + 1; LL upper = ( myinstance + 1 ) * h; if (myinstance == instances - 2) upper = depth; if (myinstance != instances - 1) { //cout << myinstance << " " << lower << " " << upper << endl; PutLL(instances - 1, findBlocker(lower, upper)); Send(instances - 1); return 0; } LL shift = 0; for (int i=0; i<instances - 1; i++) { Receive(i); LL s = GetLL(i); //cout << i << "r " << s << endl; if (s > shift) shift = s; } shift = depth - disks - shift + 1; if (shift < 0) shift = 0; cout << shift << endl; 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 | #include "message.h" #include "krazki.h" #include <vector> #include <iostream> using namespace std; typedef long long int LL; LL depth; LL disks; int instances ; LL findBlocker(LL upper, LL lower) { if (depth < disks) return 0; if (lower == 0) return 0; // -- upper (1) inclusive LL h = lower-upper+1; // ---- vector<LL> pipeDiamater(h); // -- lower (3) inclusive // -- // - total depth (5) pipeDiamater[0]=HoleDiameter(upper); for(LL i=1; i < h; i++) { pipeDiamater[i]=HoleDiameter(i+upper); if (pipeDiamater[i] > pipeDiamater[i-1]) pipeDiamater[i]=pipeDiamater[i-1]; // lejek \ / pipeline[0] } // \ / pipeline[1] LL filled = 0; LL minSize = pipeDiamater[h-1]; LL shift = 0; LL stacked = 0; for(LL i=1; i<=disks; i++) { LL size = DiscDiameter(i); //cout << "disk: " << i << " size: " << size << " " << shift << " " << stacked << " min size: " << minSize << endl; if (size <= minSize) // przechodzi { if (stacked) minSize = pipeDiamater[--stacked-1]; continue; } else // nie przechodzi - szukam, gdzie sie zatrzyma { LL blockIndex = (stacked != 0 ? stacked : h-1); while ((blockIndex>=0) && (size > pipeDiamater[blockIndex])) blockIndex-- ; shift = depth - upper - blockIndex - i + 1; // depth - upper <- tyle powinno wejsc dyskow, weszlo juz i, teraz zacielo sie na wysokosci blockIndex if ( blockIndex > 0 ) { minSize = pipeDiamater[blockIndex-1]; // pierwsze wolne miejsce stacked = blockIndex; // miejsce gdzie zablokowal sie ostatni krazek } } if (stacked == 1) break; if (shift >= depth - i + 1) break; // wystaje gora if (shift + upper + i - 2 >= depth) break; // opieramy sie o dno } return shift; } int main() { instances = NumberOfNodes(); depth = PipeHeight(); disks = NumberOfDiscs(); LL h = depth/(instances - 1); int myinstance = MyNodeId(); LL lower = myinstance * h + 1; LL upper = ( myinstance + 1 ) * h; if (myinstance == instances - 2) upper = depth; if (myinstance != instances - 1) { //cout << myinstance << " " << lower << " " << upper << endl; PutLL(instances - 1, findBlocker(lower, upper)); Send(instances - 1); return 0; } LL shift = 0; for (int i=0; i<instances - 1; i++) { Receive(i); LL s = GetLL(i); //cout << i << "r " << s << endl; if (s > shift) shift = s; } shift = depth - disks - shift + 1; if (shift < 0) shift = 0; cout << shift << endl; return 0; } |