#include <cstdlib> #include <cstdio> #include <vector> #include "krazki.h" #include "message.h" #define MIN(x, y) ((x)<(y)?x:y) #define LL long long int using namespace std; int myNodeId; int numOfNodes; int firstHoleNum, lastHoleNum; int generalCapacity, myCapacity; bool isFirstNode, isLastNode, isUnusedNode; vector<long long int> realDiameter; int numberOfDiscs; void calculateGeneralInfo(void) { myNodeId = MyNodeId(); numOfNodes = MIN(PipeHeight(), NumberOfNodes()); isFirstNode = (myNodeId == 0); isLastNode = (myNodeId == numOfNodes - 1); isUnusedNode = (myNodeId >= numOfNodes); generalCapacity = PipeHeight() / numOfNodes; firstHoleNum = isFirstNode ? 0 : myNodeId * generalCapacity; lastHoleNum = isLastNode ? PipeHeight() - 1 : firstHoleNum + generalCapacity - 1; myCapacity = lastHoleNum - firstHoleNum + 1; numberOfDiscs = NumberOfDiscs(); } LL receiveLastMinimum(void) { if (isFirstNode) return (long long int)(1000000000) * (long long int)(1000000000) + 5; return GetLL(Receive(myNodeId - 1)); } // receive ID of last packed disc int receiveLastDict(void) { if (isLastNode) return 0; return GetInt(Receive(myNodeId + 1)); } void sendLastDisc(int lastDisc) { if (!isFirstNode){ PutInt(myNodeId - 1, lastDisc); Send(myNodeId - 1); } else if (lastDisc < numberOfDiscs) { printf("0\n"); } } int main() { calculateGeneralInfo(); if (isUnusedNode) return EXIT_SUCCESS; // download holes realDiameter.resize(myCapacity); for (int i=0; i<myCapacity; ++i) realDiameter[i] = HoleDiameter(firstHoleNum + i + 1); // Calculate my realDiameters LL currentMinimum = receiveLastMinimum(); for (int i=0; i<myCapacity; ++i){ currentMinimum = MIN(currentMinimum, realDiameter[i]); realDiameter[i] = currentMinimum; } // Send currrent realDiameter to the next node (if any) if (!isLastNode){ PutLL(myNodeId + 1, currentMinimum); Send(myNodeId + 1); } int lastDisc = receiveLastDict(); if (lastDisc == numberOfDiscs) sendLastDisc(lastDisc); else { for (int i=0; i<myCapacity; ++i){ if (DiscDiameter(lastDisc+1) <= realDiameter[myCapacity - 1 - i]) { lastDisc += 1; // printf("Disc %d packed into hole %d\n", lastDisc, lastHoleNum - i + 1); if (lastDisc == numberOfDiscs) { printf("%d\n", lastHoleNum - i + 1); break; } } } } sendLastDisc(lastDisc); return EXIT_SUCCESS; }
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 | #include <cstdlib> #include <cstdio> #include <vector> #include "krazki.h" #include "message.h" #define MIN(x, y) ((x)<(y)?x:y) #define LL long long int using namespace std; int myNodeId; int numOfNodes; int firstHoleNum, lastHoleNum; int generalCapacity, myCapacity; bool isFirstNode, isLastNode, isUnusedNode; vector<long long int> realDiameter; int numberOfDiscs; void calculateGeneralInfo(void) { myNodeId = MyNodeId(); numOfNodes = MIN(PipeHeight(), NumberOfNodes()); isFirstNode = (myNodeId == 0); isLastNode = (myNodeId == numOfNodes - 1); isUnusedNode = (myNodeId >= numOfNodes); generalCapacity = PipeHeight() / numOfNodes; firstHoleNum = isFirstNode ? 0 : myNodeId * generalCapacity; lastHoleNum = isLastNode ? PipeHeight() - 1 : firstHoleNum + generalCapacity - 1; myCapacity = lastHoleNum - firstHoleNum + 1; numberOfDiscs = NumberOfDiscs(); } LL receiveLastMinimum(void) { if (isFirstNode) return (long long int)(1000000000) * (long long int)(1000000000) + 5; return GetLL(Receive(myNodeId - 1)); } // receive ID of last packed disc int receiveLastDict(void) { if (isLastNode) return 0; return GetInt(Receive(myNodeId + 1)); } void sendLastDisc(int lastDisc) { if (!isFirstNode){ PutInt(myNodeId - 1, lastDisc); Send(myNodeId - 1); } else if (lastDisc < numberOfDiscs) { printf("0\n"); } } int main() { calculateGeneralInfo(); if (isUnusedNode) return EXIT_SUCCESS; // download holes realDiameter.resize(myCapacity); for (int i=0; i<myCapacity; ++i) realDiameter[i] = HoleDiameter(firstHoleNum + i + 1); // Calculate my realDiameters LL currentMinimum = receiveLastMinimum(); for (int i=0; i<myCapacity; ++i){ currentMinimum = MIN(currentMinimum, realDiameter[i]); realDiameter[i] = currentMinimum; } // Send currrent realDiameter to the next node (if any) if (!isLastNode){ PutLL(myNodeId + 1, currentMinimum); Send(myNodeId + 1); } int lastDisc = receiveLastDict(); if (lastDisc == numberOfDiscs) sendLastDisc(lastDisc); else { for (int i=0; i<myCapacity; ++i){ if (DiscDiameter(lastDisc+1) <= realDiameter[myCapacity - 1 - i]) { lastDisc += 1; // printf("Disc %d packed into hole %d\n", lastDisc, lastHoleNum - i + 1); if (lastDisc == numberOfDiscs) { printf("%d\n", lastHoleNum - i + 1); break; } } } } sendLastDisc(lastDisc); return EXIT_SUCCESS; } |