Niestety, nie byliśmy w stanie w pełni poprawnie wyświetlić tego pliku, ponieważ nie jest zakodowany w UTF-8.
Możesz pobrać ten plik i spróbować otworzyć go samodzielnie.
#include "krazki.h" #include "message.h" #include <stdio.h> #include <algorithm> using namespace std; bool comp(long long a, long long b) { return a>b; } //Binary function that accepts two arguments (the first is always val, //and the second of the type pointed by ForwardIterator), and // returns a value convertible to bool. //The value returned indicates whether the first argument is considered to go before the second. //The function shall not modify any of its arguments. //This can either be a function pointer or a function object. int main() { int nodes = NumberOfNodes(); int pipeheight = PipeHeight(); int numdiscs = NumberOfDiscs(); int mynode = MyNodeId(); if (pipeheight<numdiscs) { if (mynode==0) printf("0\n"); return 0; } if (pipeheight<100000) { nodes = 1; if (mynode>0) return 0; } int low_pipe = (long long) mynode*pipeheight/nodes; int high_pipe = (long long) (mynode+1)*pipeheight/nodes; int low_disc = (long long) mynode*numdiscs/nodes; int high_disc = (long long) (mynode+1)*numdiscs/nodes; long long* pipe_buffer; long long* disc_buffer; long long min_pipe[nodes]; min_pipe[mynode] = 1000000000000000015LL; for (int i=low_pipe+1; i<=high_pipe; ++i) { long long a = HoleDiameter(i); if (a<min_pipe[mynode]) min_pipe[mynode] = a; } long long max_disc[nodes]; max_disc[mynode] = -1; for (int i=low_disc+1; i<=high_disc; ++i) { long long a = DiscDiameter(i); //pipe_buffer[i-low_pipe-1] = a; if (a>max_disc[mynode]) max_disc[mynode] = a; } // printf("min_pipe=%ld max_disc=%ld", min_pipe, max_disc); for (int i=0; i<nodes; ++i) { if (i!=mynode) { PutLL(i, min_pipe[mynode]); PutLL(i, max_disc[mynode]); Send(i); } } for (int i=0; i<nodes; ++i) { if (i!=mynode) { Receive(i); min_pipe[i] = GetLL(i); max_disc[i] = GetLL(i); } } for (int i=1; i<nodes; ++i) { min_pipe[i] = min(min_pipe[i], min_pipe[i-1]); max_disc[i] = max(max_disc[i], max_disc[i-1]); } int pipe_to_check = -1; for (int i=0; i<nodes; ++i) { if (max_disc[mynode] > min_pipe[i]) { pipe_to_check = i; break; } } int stack = 1000000000; // allow enough disc elements to fall thru if (pipe_to_check == -1) { // moja czesc dysk�w przeleci po prostu przez cala rure; nic nie rob } else { low_pipe = (long long) pipe_to_check*pipeheight/nodes; high_pipe = (long long) (pipe_to_check+1)*pipeheight/nodes; pipe_buffer = new long long [high_pipe-low_pipe+10]; long long cur_min; if (pipe_to_check>0) cur_min = min_pipe[pipe_to_check-1]; else cur_min = 1000000000000000015LL; for (int i=low_pipe+1; i<=high_pipe; ++i) { long long a = HoleDiameter(i); a = min(a, cur_min); cur_min = a; pipe_buffer[i-low_pipe-1] = a; } disc_buffer = new long long [high_disc-low_disc+10]; long long cur_max; if (mynode>0) cur_max = max_disc[mynode-1]; else cur_max = 0; stack = 1000000000; // allow enough disc elements to fall thru // stack means the position of last element put there for (int i=low_disc+1; i<=high_disc; ++i) { long long a = DiscDiameter(i); a = max(a, cur_max); cur_max = a; disc_buffer[i-low_disc-1] = a; // where does "a" fall on pipe? long long * pos = upper_bound(pipe_buffer, pipe_buffer+high_pipe-low_pipe, a, comp); // first "greater" (i.e. lower) if (pos >= pipe_buffer+high_pipe-low_pipe) { // fell thru stack --; // just assume it fell on the other ones } else { int stopped_at = (pos-pipe_buffer); // this is the index that when 0 means the item stopped at on low_pipe+1 // (so is on low_pipe, but stopped at low_pipe+1); max is high_pipe-low_pipe-1; min is 0 if (low_pipe+stopped_at < stack) stack = low_pipe+stopped_at; // low_pipe+stopped_at - stack is now the new last element else stack --; // so if it would fall thru to further than current cursor, just assume it enlarges the stack } } // now we are thru; stack is the position of the "shallowest" element in the pipe // stack can be also theoretically bigger than "high_pipe+(high_disc-low_disc)+1". then it means all elements fell thru } if (mynode != 0) { PutInt(0, stack); Send(0); } else { int deep_stack = 1000000000; for (int i=nodes-1; i>=0; --i) { int i_stack; if (i>0) { Receive(i); i_stack = GetInt(i); } else { i_stack = stack; } int low_disc = (long long)i*numdiscs/nodes; int high_disc = (long long)(i+1)*numdiscs/nodes; int num_discs = high_disc - low_disc; // this many disks tried to put and shallowest ended at i_stack if (deep_stack-num_discs < i_stack) { deep_stack = deep_stack-num_discs; } else { deep_stack = i_stack; } } if (deep_stack > pipeheight) deep_stack = pipeheight - numdiscs + 1; else if (deep_stack < 0) deep_stack = 0; printf("%d\n", deep_stack); } 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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | #include "krazki.h" #include "message.h" #include <stdio.h> #include <algorithm> using namespace std; bool comp(long long a, long long b) { return a>b; } //Binary function that accepts two arguments (the first is always val, //and the second of the type pointed by ForwardIterator), and // returns a value convertible to bool. //The value returned indicates whether the first argument is considered to go before the second. //The function shall not modify any of its arguments. //This can either be a function pointer or a function object. int main() { int nodes = NumberOfNodes(); int pipeheight = PipeHeight(); int numdiscs = NumberOfDiscs(); int mynode = MyNodeId(); if (pipeheight<numdiscs) { if (mynode==0) printf("0\n"); return 0; } if (pipeheight<100000) { nodes = 1; if (mynode>0) return 0; } int low_pipe = (long long) mynode*pipeheight/nodes; int high_pipe = (long long) (mynode+1)*pipeheight/nodes; int low_disc = (long long) mynode*numdiscs/nodes; int high_disc = (long long) (mynode+1)*numdiscs/nodes; long long* pipe_buffer; long long* disc_buffer; long long min_pipe[nodes]; min_pipe[mynode] = 1000000000000000015LL; for (int i=low_pipe+1; i<=high_pipe; ++i) { long long a = HoleDiameter(i); if (a<min_pipe[mynode]) min_pipe[mynode] = a; } long long max_disc[nodes]; max_disc[mynode] = -1; for (int i=low_disc+1; i<=high_disc; ++i) { long long a = DiscDiameter(i); //pipe_buffer[i-low_pipe-1] = a; if (a>max_disc[mynode]) max_disc[mynode] = a; } // printf("min_pipe=%ld max_disc=%ld", min_pipe, max_disc); for (int i=0; i<nodes; ++i) { if (i!=mynode) { PutLL(i, min_pipe[mynode]); PutLL(i, max_disc[mynode]); Send(i); } } for (int i=0; i<nodes; ++i) { if (i!=mynode) { Receive(i); min_pipe[i] = GetLL(i); max_disc[i] = GetLL(i); } } for (int i=1; i<nodes; ++i) { min_pipe[i] = min(min_pipe[i], min_pipe[i-1]); max_disc[i] = max(max_disc[i], max_disc[i-1]); } int pipe_to_check = -1; for (int i=0; i<nodes; ++i) { if (max_disc[mynode] > min_pipe[i]) { pipe_to_check = i; break; } } int stack = 1000000000; // allow enough disc elements to fall thru if (pipe_to_check == -1) { // moja czesc dysk�w przeleci po prostu przez cala rure; nic nie rob } else { low_pipe = (long long) pipe_to_check*pipeheight/nodes; high_pipe = (long long) (pipe_to_check+1)*pipeheight/nodes; pipe_buffer = new long long [high_pipe-low_pipe+10]; long long cur_min; if (pipe_to_check>0) cur_min = min_pipe[pipe_to_check-1]; else cur_min = 1000000000000000015LL; for (int i=low_pipe+1; i<=high_pipe; ++i) { long long a = HoleDiameter(i); a = min(a, cur_min); cur_min = a; pipe_buffer[i-low_pipe-1] = a; } disc_buffer = new long long [high_disc-low_disc+10]; long long cur_max; if (mynode>0) cur_max = max_disc[mynode-1]; else cur_max = 0; stack = 1000000000; // allow enough disc elements to fall thru // stack means the position of last element put there for (int i=low_disc+1; i<=high_disc; ++i) { long long a = DiscDiameter(i); a = max(a, cur_max); cur_max = a; disc_buffer[i-low_disc-1] = a; // where does "a" fall on pipe? long long * pos = upper_bound(pipe_buffer, pipe_buffer+high_pipe-low_pipe, a, comp); // first "greater" (i.e. lower) if (pos >= pipe_buffer+high_pipe-low_pipe) { // fell thru stack --; // just assume it fell on the other ones } else { int stopped_at = (pos-pipe_buffer); // this is the index that when 0 means the item stopped at on low_pipe+1 // (so is on low_pipe, but stopped at low_pipe+1); max is high_pipe-low_pipe-1; min is 0 if (low_pipe+stopped_at < stack) stack = low_pipe+stopped_at; // low_pipe+stopped_at - stack is now the new last element else stack --; // so if it would fall thru to further than current cursor, just assume it enlarges the stack } } // now we are thru; stack is the position of the "shallowest" element in the pipe // stack can be also theoretically bigger than "high_pipe+(high_disc-low_disc)+1". then it means all elements fell thru } if (mynode != 0) { PutInt(0, stack); Send(0); } else { int deep_stack = 1000000000; for (int i=nodes-1; i>=0; --i) { int i_stack; if (i>0) { Receive(i); i_stack = GetInt(i); } else { i_stack = stack; } int low_disc = (long long)i*numdiscs/nodes; int high_disc = (long long)(i+1)*numdiscs/nodes; int num_discs = high_disc - low_disc; // this many disks tried to put and shallowest ended at i_stack if (deep_stack-num_discs < i_stack) { deep_stack = deep_stack-num_discs; } else { deep_stack = i_stack; } } if (deep_stack > pipeheight) deep_stack = pipeheight - numdiscs + 1; else if (deep_stack < 0) deep_stack = 0; printf("%d\n", deep_stack); } return 0; } |