#include "krazki.h" #include "message.h" #include <algorithm> #include <iostream> #include <vector> using namespace std; int main() { int n = PipeHeight(); int m = NumberOfDiscs(); vector<long long int> mins; int id = MyNodeId(); int instances = NumberOfNodes(); int pipesPerInstance; if (n <= instances) { pipesPerInstance = 1; instances = n; } else if (n % instances == 0) { pipesPerInstance = n/instances; } else { pipesPerInstance = 1 + n/instances; if (n % pipesPerInstance == 0) { instances = n / pipesPerInstance; } else { instances = 1 + n/pipesPerInstance; } } if (id >= instances) { return 0; } int firstPipe = id * pipesPerInstance; mins.resize(pipesPerInstance); mins[0] = HoleDiameter(firstPipe + 1); int i = 1; for (; (i < pipesPerInstance) && (i + firstPipe < n); ++i) { mins[i] = min(mins[i - 1], HoleDiameter(i + firstPipe + 1)); } //i is after last pipe for instance long long int prev_inst_min; int j; if (id > 0) { Receive(id - 1); prev_inst_min = GetLL(id - 1); j = 0; while (j < i && prev_inst_min < mins[j]) { mins[j] = prev_inst_min; ++j; } } if (id < instances - 1) { PutLL(id + 1, mins[i - 1]); Send(id + 1); } int k; int global_level = n; if (id < instances-1) { Receive(id + 1); k = GetInt(id + 1); global_level = GetInt(id + 1); } else { k = 0; } long long int discDiameter; int current_level = i - 1; bool stop = false; while(!stop && k < m) { discDiameter = DiscDiameter(k + 1); while(current_level >= 0 && discDiameter > mins[current_level]) { --current_level; --global_level; } if (current_level < 0) { //przepelniony stop = true; if(id > 0) { PutInt(id - 1, k); PutInt(id - 1, global_level); Send(id - 1); return 0; } } else { //wejdzie, bierzemy nastepny dysk --current_level; --global_level; ++k; } } if (id > 0) { PutInt(id - 1, k); PutInt(id - 1, global_level); Send(id - 1); } else { if (k >= m) { cout << global_level + 1; } else { //nie wszystko weszlo cout << 0; } } 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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | #include "krazki.h" #include "message.h" #include <algorithm> #include <iostream> #include <vector> using namespace std; int main() { int n = PipeHeight(); int m = NumberOfDiscs(); vector<long long int> mins; int id = MyNodeId(); int instances = NumberOfNodes(); int pipesPerInstance; if (n <= instances) { pipesPerInstance = 1; instances = n; } else if (n % instances == 0) { pipesPerInstance = n/instances; } else { pipesPerInstance = 1 + n/instances; if (n % pipesPerInstance == 0) { instances = n / pipesPerInstance; } else { instances = 1 + n/pipesPerInstance; } } if (id >= instances) { return 0; } int firstPipe = id * pipesPerInstance; mins.resize(pipesPerInstance); mins[0] = HoleDiameter(firstPipe + 1); int i = 1; for (; (i < pipesPerInstance) && (i + firstPipe < n); ++i) { mins[i] = min(mins[i - 1], HoleDiameter(i + firstPipe + 1)); } //i is after last pipe for instance long long int prev_inst_min; int j; if (id > 0) { Receive(id - 1); prev_inst_min = GetLL(id - 1); j = 0; while (j < i && prev_inst_min < mins[j]) { mins[j] = prev_inst_min; ++j; } } if (id < instances - 1) { PutLL(id + 1, mins[i - 1]); Send(id + 1); } int k; int global_level = n; if (id < instances-1) { Receive(id + 1); k = GetInt(id + 1); global_level = GetInt(id + 1); } else { k = 0; } long long int discDiameter; int current_level = i - 1; bool stop = false; while(!stop && k < m) { discDiameter = DiscDiameter(k + 1); while(current_level >= 0 && discDiameter > mins[current_level]) { --current_level; --global_level; } if (current_level < 0) { //przepelniony stop = true; if(id > 0) { PutInt(id - 1, k); PutInt(id - 1, global_level); Send(id - 1); return 0; } } else { //wejdzie, bierzemy nastepny dysk --current_level; --global_level; ++k; } } if (id > 0) { PutInt(id - 1, k); PutInt(id - 1, global_level); Send(id - 1); } else { if (k >= m) { cout << global_level + 1; } else { //nie wszystko weszlo cout << 0; } } return 0; } |