#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; } | 
 
            
         English
                    English