#include <cstdio> #include "kollib.h" #include "message.h" using namespace std; struct node { int time; bool isPositive; }; int NoS; int NoQ; node * roulette; int * positions; int * positions2; void createRoulette() { roulette = new node[NoS]; positions = new int[NoS]; positions2 = new int[NoS]; int i, n2 = NoS-1, half; int pos = 1, next, last = 1, len = 0; positions[0] = 0; positions2[0] = 1; roulette[0].isPositive = false; if(n2 % 2) // nieparzyste 1, 3, 5, ... half = (n2 >> 1) + 1; else // parzyste 0, 2, 4, ... half = (n2 >> 1); for(i = 1; i <= n2; ++i) { next = SecondNeighbor(pos); if(next == last) next = FirstNeighbor(pos); positions[next-1] = i; positions2[i] = next; if(i > half) { if(!(i == half+1 && !(n2 % 2))) --len; roulette[next-1].isPositive = true; } else { ++len; roulette[next-1].isPositive = false; } roulette[next-1].time = len; last = pos; pos = next; } } inline int getDistance(const int & pos, const int & offset) { int p = pos + offset; if( p >= NoS ) p -= NoS; else if( p < 0 ) p += NoS; return roulette[ positions2[ p ]-1 ].time; } inline int getTime(const int & from, const int & to) { if( from == to ) return 0; int offset = roulette[ from-1 ].time; if( !roulette[ from-1 ].isPositive ) offset = -offset; return getDistance(positions[ to-1 ], offset); } int main() { if(MyNodeId() > 0) { NoS = NumberOfStudents(); NoQ = NumberOfQueries(); createRoulette(); for(int query = MyNodeId(); query <= NumberOfQueries(); query += NumberOfNodes() - 1) { PutInt(0, getTime( QueryFrom(query), QueryTo(query) )); Send(0); } } else { int received = 0; while(1) { for(int instance = 1; instance < NumberOfNodes(); ++instance) { if(received >= NumberOfQueries()) goto end; Receive(instance); printf("%d\n", GetInt(instance)); ++received; } } } end: delete positions; delete positions2; delete roulette; 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 | #include <cstdio> #include "kollib.h" #include "message.h" using namespace std; struct node { int time; bool isPositive; }; int NoS; int NoQ; node * roulette; int * positions; int * positions2; void createRoulette() { roulette = new node[NoS]; positions = new int[NoS]; positions2 = new int[NoS]; int i, n2 = NoS-1, half; int pos = 1, next, last = 1, len = 0; positions[0] = 0; positions2[0] = 1; roulette[0].isPositive = false; if(n2 % 2) // nieparzyste 1, 3, 5, ... half = (n2 >> 1) + 1; else // parzyste 0, 2, 4, ... half = (n2 >> 1); for(i = 1; i <= n2; ++i) { next = SecondNeighbor(pos); if(next == last) next = FirstNeighbor(pos); positions[next-1] = i; positions2[i] = next; if(i > half) { if(!(i == half+1 && !(n2 % 2))) --len; roulette[next-1].isPositive = true; } else { ++len; roulette[next-1].isPositive = false; } roulette[next-1].time = len; last = pos; pos = next; } } inline int getDistance(const int & pos, const int & offset) { int p = pos + offset; if( p >= NoS ) p -= NoS; else if( p < 0 ) p += NoS; return roulette[ positions2[ p ]-1 ].time; } inline int getTime(const int & from, const int & to) { if( from == to ) return 0; int offset = roulette[ from-1 ].time; if( !roulette[ from-1 ].isPositive ) offset = -offset; return getDistance(positions[ to-1 ], offset); } int main() { if(MyNodeId() > 0) { NoS = NumberOfStudents(); NoQ = NumberOfQueries(); createRoulette(); for(int query = MyNodeId(); query <= NumberOfQueries(); query += NumberOfNodes() - 1) { PutInt(0, getTime( QueryFrom(query), QueryTo(query) )); Send(0); } } else { int received = 0; while(1) { for(int instance = 1; instance < NumberOfNodes(); ++instance) { if(received >= NumberOfQueries()) goto end; Receive(instance); printf("%d\n", GetInt(instance)); ++received; } } } end: delete positions; delete positions2; delete roulette; return (0); } |