#include <cstdlib> #include <iostream> #include "krazki.h" #include "message.h" const int N = 1000002; long long r[N]; long long wyniki[200]; int main() { int nWalcow = PipeHeight(); int nKrazkow = NumberOfDiscs(); if(nKrazkow > nWalcow) { std::cout << 0; return 0;} long long poczSrednica,koncowaSrednica; long long srednicaDysku; int i, j, lewy, prawy, srodek, nWezlow, wynik = 0; //wyrownanie walcow int poczatek = (MyNodeId() * nWalcow) / NumberOfNodes(); int koniec ; if(((MyNodeId() + 1) * nWalcow) / NumberOfNodes() < nWalcow) koniec = ((MyNodeId() + 1) * nWalcow) / NumberOfNodes(); else koniec = nWalcow; r[0] = HoleDiameter(poczatek); for (i = poczatek + 1, j = 0; i < koniec; ++i, ++j) { r[j] = HoleDiameter(i); if(r[j] > r[j-1]) r[j] = r[j-1]; } nWezlow = poczatek - koniec; poczSrednica = r[0]; koncowaSrednica = r[nWezlow-1]; //wysylanie srednic walcow if (MyNodeId() > 0) { PutLL(0, poczSrednica); PutLL(0, koncowaSrednica); Send(0); } else { wyniki[0] = poczSrednica; wyniki[1] = koncowaSrednica; for ( i = 1,j = 2; i < NumberOfNodes(); i++,j= j + 2) { Receive(i); long long otrzymanaLiczbaPocz = GetLL(i); long long otrzymanaLiczbaKon = GetLL(i); if(otrzymanaLiczbaPocz <= wyniki[j-1]){ wyniki[j] = otrzymanaLiczbaPocz; } else { wyniki[j] = wyniki[j-1]; } PutLL(i, wyniki[j]); Send(i); //wyniki[j+1] = std::LLONG_MIN(otrzymanaLiczbaKon,wyniki[j]); if (wyniki[j] < otrzymanaLiczbaKon) wyniki[j+1] = wyniki[j]; else wyniki[j+1]=otrzymanaLiczbaKon; } } //poprawianie srednic walcow w wezlach if (MyNodeId() > 0) { Receive(0); long long otrzymanaSrednica = GetLL(0); for(j = 0 ; j < nWezlow && r[j] > otrzymanaSrednica; ++j) r[j] = otrzymanaSrednica; } //ustawianie krazkow if (MyNodeId() == NumberOfNodes() - 1) { int poczKrazkow = 0; int konKrazkow ; if((nWalcow)/NumberOfNodes() < nKrazkow) konKrazkow= (nWalcow)/NumberOfNodes() ; else konKrazkow = nKrazkow; int wysokosc = konKrazkow - poczKrazkow; prawy = nWezlow - 1; lewy = 0; for (i = poczKrazkow, j = 0; i < konKrazkow; ++i, ++j) { srednicaDysku = DiscDiameter(i); if (prawy >= 0) { lewy = 0; while(lewy < prawy) { srodek = (lewy + prawy + 1)/2; if(srednicaDysku > r[srodek] ) prawy = srodek + 1; else lewy = srodek; } prawy--; } else break; } wynik = wynik + j; } //odebranie informacji else { Receive(MyNodeId() + 1); int otrzymanyPoczatek = GetInt(MyNodeId() + 1); Receive(MyNodeId() + 1); wynik = GetInt(MyNodeId() + 1); int poczKrazkow = otrzymanyPoczatek; int konKrazkow ; if(otrzymanyPoczatek + nWalcow/NumberOfNodes() < nKrazkow) konKrazkow = otrzymanyPoczatek + nWalcow/NumberOfNodes(); else konKrazkow = nKrazkow; int wysokosc = konKrazkow - poczKrazkow; prawy = nWezlow - 1; for (i = poczKrazkow, j = 0; i < konKrazkow; ++i, ++j) { srednicaDysku = DiscDiameter(i); if (prawy >= 0) { lewy = 0; while(lewy < prawy) { srodek = (lewy + prawy + 1)/2; if(srednicaDysku > r[srodek] ) prawy = srodek + 1; else lewy = srodek; } prawy--; } else break; } wynik = wynik + j; } //////////////////////// if (MyNodeId() > 0) { PutInt(MyNodeId() - 1, i);//ostatni nieuwzgledniony krazek Send(MyNodeId() - 1); PutInt(MyNodeId() - 1, wynik);//liczba walcow Send(MyNodeId() - 1) ; } else{ if(i < nKrazkow) wynik = nWalcow - wynik; else wynik = 0; std::cout << wynik << std::endl; return 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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | #include <cstdlib> #include <iostream> #include "krazki.h" #include "message.h" const int N = 1000002; long long r[N]; long long wyniki[200]; int main() { int nWalcow = PipeHeight(); int nKrazkow = NumberOfDiscs(); if(nKrazkow > nWalcow) { std::cout << 0; return 0;} long long poczSrednica,koncowaSrednica; long long srednicaDysku; int i, j, lewy, prawy, srodek, nWezlow, wynik = 0; //wyrownanie walcow int poczatek = (MyNodeId() * nWalcow) / NumberOfNodes(); int koniec ; if(((MyNodeId() + 1) * nWalcow) / NumberOfNodes() < nWalcow) koniec = ((MyNodeId() + 1) * nWalcow) / NumberOfNodes(); else koniec = nWalcow; r[0] = HoleDiameter(poczatek); for (i = poczatek + 1, j = 0; i < koniec; ++i, ++j) { r[j] = HoleDiameter(i); if(r[j] > r[j-1]) r[j] = r[j-1]; } nWezlow = poczatek - koniec; poczSrednica = r[0]; koncowaSrednica = r[nWezlow-1]; //wysylanie srednic walcow if (MyNodeId() > 0) { PutLL(0, poczSrednica); PutLL(0, koncowaSrednica); Send(0); } else { wyniki[0] = poczSrednica; wyniki[1] = koncowaSrednica; for ( i = 1,j = 2; i < NumberOfNodes(); i++,j= j + 2) { Receive(i); long long otrzymanaLiczbaPocz = GetLL(i); long long otrzymanaLiczbaKon = GetLL(i); if(otrzymanaLiczbaPocz <= wyniki[j-1]){ wyniki[j] = otrzymanaLiczbaPocz; } else { wyniki[j] = wyniki[j-1]; } PutLL(i, wyniki[j]); Send(i); //wyniki[j+1] = std::LLONG_MIN(otrzymanaLiczbaKon,wyniki[j]); if (wyniki[j] < otrzymanaLiczbaKon) wyniki[j+1] = wyniki[j]; else wyniki[j+1]=otrzymanaLiczbaKon; } } //poprawianie srednic walcow w wezlach if (MyNodeId() > 0) { Receive(0); long long otrzymanaSrednica = GetLL(0); for(j = 0 ; j < nWezlow && r[j] > otrzymanaSrednica; ++j) r[j] = otrzymanaSrednica; } //ustawianie krazkow if (MyNodeId() == NumberOfNodes() - 1) { int poczKrazkow = 0; int konKrazkow ; if((nWalcow)/NumberOfNodes() < nKrazkow) konKrazkow= (nWalcow)/NumberOfNodes() ; else konKrazkow = nKrazkow; int wysokosc = konKrazkow - poczKrazkow; prawy = nWezlow - 1; lewy = 0; for (i = poczKrazkow, j = 0; i < konKrazkow; ++i, ++j) { srednicaDysku = DiscDiameter(i); if (prawy >= 0) { lewy = 0; while(lewy < prawy) { srodek = (lewy + prawy + 1)/2; if(srednicaDysku > r[srodek] ) prawy = srodek + 1; else lewy = srodek; } prawy--; } else break; } wynik = wynik + j; } //odebranie informacji else { Receive(MyNodeId() + 1); int otrzymanyPoczatek = GetInt(MyNodeId() + 1); Receive(MyNodeId() + 1); wynik = GetInt(MyNodeId() + 1); int poczKrazkow = otrzymanyPoczatek; int konKrazkow ; if(otrzymanyPoczatek + nWalcow/NumberOfNodes() < nKrazkow) konKrazkow = otrzymanyPoczatek + nWalcow/NumberOfNodes(); else konKrazkow = nKrazkow; int wysokosc = konKrazkow - poczKrazkow; prawy = nWezlow - 1; for (i = poczKrazkow, j = 0; i < konKrazkow; ++i, ++j) { srednicaDysku = DiscDiameter(i); if (prawy >= 0) { lewy = 0; while(lewy < prawy) { srodek = (lewy + prawy + 1)/2; if(srednicaDysku > r[srodek] ) prawy = srodek + 1; else lewy = srodek; } prawy--; } else break; } wynik = wynik + j; } //////////////////////// if (MyNodeId() > 0) { PutInt(MyNodeId() - 1, i);//ostatni nieuwzgledniony krazek Send(MyNodeId() - 1); PutInt(MyNodeId() - 1, wynik);//liczba walcow Send(MyNodeId() - 1) ; } else{ if(i < nKrazkow) wynik = nWalcow - wynik; else wynik = 0; std::cout << wynik << std::endl; return 0; } return 0; } |