#include <algorithm> #include <cstdio> #include <cstdlib> #include "message.h" #include "kanapka.h" static const unsigned int MAX_INSTANCES = 100; typedef long long ll; static int myID; static int numberOfNodes; static ll sandwichLength; struct stats_t { ll prefixMin; ll suffixMin; ll innerMin; ll sum; } stats; void slaveWork() { const ll beginRange = (sandwichLength * (ll)myID) / (ll)numberOfNodes; const ll endRange = (sandwichLength * (ll)(myID + 1)) / (ll)numberOfNodes; const ll rangeSize = endRange - beginRange; // Calculate statistics ll prefixMin = 0, prefixMax = 0, innerMin = 0; ll sum = 0, minSum = 0; for (int i = beginRange; i < endRange; i++) { const ll current = GetTaste(i); sum += current; prefixMin = std::min(prefixMin, sum); prefixMax = std::max(prefixMax, sum); minSum = std::min(minSum + current, 0LL); innerMin = std::min(innerMin, minSum); } stats.prefixMin = prefixMin; stats.suffixMin = sum - prefixMax; stats.innerMin = innerMin; stats.sum = sum; // Send statistics to master (if this instance is not master itself) if (myID != 0) { PutLL(0, stats.prefixMin); PutLL(0, stats.suffixMin); PutLL(0, stats.innerMin); PutLL(0, stats.sum); Send(0); } } void masterWork() { stats_t combinedStats = stats; // printf("%lld %lld %lld %lld\n", stats.prefixMin, stats.suffixMin, stats.innerMin, stats.sum); for (int i = 1; i < numberOfNodes; i++) { stats_t receivedStats, newStats; Receive(i); receivedStats.prefixMin = GetLL(i); receivedStats.suffixMin = GetLL(i); receivedStats.innerMin = GetLL(i); receivedStats.sum = GetLL(i); // printf("R: %lld %lld %lld %lld\n", receivedStats.prefixMin, receivedStats.suffixMin, receivedStats.innerMin, receivedStats.sum); // printf("C: %lld %lld %lld %lld\n", combinedStats.prefixMin, combinedStats.suffixMin, combinedStats.innerMin, combinedStats.sum); newStats.prefixMin = std::min(combinedStats.prefixMin, combinedStats.sum + receivedStats.prefixMin); newStats.suffixMin = std::min(receivedStats.suffixMin, receivedStats.sum + combinedStats.suffixMin); newStats.innerMin = std::min({ combinedStats.innerMin, receivedStats.innerMin, combinedStats.suffixMin + receivedStats.prefixMin }); newStats.sum = combinedStats.sum + receivedStats.sum; combinedStats = newStats; } printf("%lld\n", combinedStats.sum - combinedStats.innerMin); } int main() { sandwichLength = GetN(); myID = MyNodeId(); numberOfNodes = (int)std::min((ll)NumberOfNodes(), sandwichLength); if (myID >= numberOfNodes) return 0; slaveWork(); if (myID == 0) masterWork(); 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 | #include <algorithm> #include <cstdio> #include <cstdlib> #include "message.h" #include "kanapka.h" static const unsigned int MAX_INSTANCES = 100; typedef long long ll; static int myID; static int numberOfNodes; static ll sandwichLength; struct stats_t { ll prefixMin; ll suffixMin; ll innerMin; ll sum; } stats; void slaveWork() { const ll beginRange = (sandwichLength * (ll)myID) / (ll)numberOfNodes; const ll endRange = (sandwichLength * (ll)(myID + 1)) / (ll)numberOfNodes; const ll rangeSize = endRange - beginRange; // Calculate statistics ll prefixMin = 0, prefixMax = 0, innerMin = 0; ll sum = 0, minSum = 0; for (int i = beginRange; i < endRange; i++) { const ll current = GetTaste(i); sum += current; prefixMin = std::min(prefixMin, sum); prefixMax = std::max(prefixMax, sum); minSum = std::min(minSum + current, 0LL); innerMin = std::min(innerMin, minSum); } stats.prefixMin = prefixMin; stats.suffixMin = sum - prefixMax; stats.innerMin = innerMin; stats.sum = sum; // Send statistics to master (if this instance is not master itself) if (myID != 0) { PutLL(0, stats.prefixMin); PutLL(0, stats.suffixMin); PutLL(0, stats.innerMin); PutLL(0, stats.sum); Send(0); } } void masterWork() { stats_t combinedStats = stats; // printf("%lld %lld %lld %lld\n", stats.prefixMin, stats.suffixMin, stats.innerMin, stats.sum); for (int i = 1; i < numberOfNodes; i++) { stats_t receivedStats, newStats; Receive(i); receivedStats.prefixMin = GetLL(i); receivedStats.suffixMin = GetLL(i); receivedStats.innerMin = GetLL(i); receivedStats.sum = GetLL(i); // printf("R: %lld %lld %lld %lld\n", receivedStats.prefixMin, receivedStats.suffixMin, receivedStats.innerMin, receivedStats.sum); // printf("C: %lld %lld %lld %lld\n", combinedStats.prefixMin, combinedStats.suffixMin, combinedStats.innerMin, combinedStats.sum); newStats.prefixMin = std::min(combinedStats.prefixMin, combinedStats.sum + receivedStats.prefixMin); newStats.suffixMin = std::min(receivedStats.suffixMin, receivedStats.sum + combinedStats.suffixMin); newStats.innerMin = std::min({ combinedStats.innerMin, receivedStats.innerMin, combinedStats.suffixMin + receivedStats.prefixMin }); newStats.sum = combinedStats.sum + receivedStats.sum; combinedStats = newStats; } printf("%lld\n", combinedStats.sum - combinedStats.innerMin); } int main() { sandwichLength = GetN(); myID = MyNodeId(); numberOfNodes = (int)std::min((ll)NumberOfNodes(), sandwichLength); if (myID >= numberOfNodes) return 0; slaveWork(); if (myID == 0) masterWork(); return 0; } |