#include "cielib.h" #define ABS(x) ((x)<0 ? -(x) : (x)) #define MIN(x, y) ((x)<(y) ? (x) : (y)) #define GREATER (int)1 #define EQUAL (int)0 #define LESS (int)(-1) #define INF 1000000005 #define DEBUG true int D, R, K, POS[505]; int DIR[505]; bool check(){ return czyCieplo(POS); } int dimPosRelation(int dim, int pos) { if (pos < 0 || pos > R) return 1; int originPos = POS[dim]; POS[dim] = pos; bool rel_1 = check(); POS[dim] = originPos; bool rel_2 = check(); if (rel_1) return LESS; if (rel_2) return GREATER; return EQUAL; } bool checkVector(int factor) { int MOVED_POS[505]; for (int i=0; i<D; ++i) MOVED_POS[i] = POS[i] + DIR[i] * factor; return czyCieplo(MOVED_POS); } int moveToEdge(int dim){ int rel_down = dimPosRelation(dim, POS[dim] - 1); int rel_up = dimPosRelation(dim, POS[dim] + 1); if (rel_down == GREATER && rel_up == GREATER) return EQUAL; if (rel_down == GREATER) return GREATER; if (rel_up == GREATER) return LESS; if (rel_down == EQUAL && rel_up == EQUAL){ rel_down = dimPosRelation(dim, 0); rel_up = dimPosRelation(dim, R); if (rel_down == EQUAL && rel_up == EQUAL) return EQUAL; int result; int boundPos; if (rel_down == GREATER){ boundPos = 0; result = GREATER; } else { boundPos = R; result = LESS; } while (POS[dim] != boundPos-1 && POS[dim] != boundPos+1){ int midPos = (boundPos + POS[dim]) / 2; if (dimPosRelation(dim, midPos) == EQUAL) POS[dim] = midPos; else boundPos = midPos; } return result; } } int main() { D = podajD(); K = podajK(); R = podajR(); for (int i=0; i<D; ++i) POS[i] = R / 2; check(); for (int i=0; i<D; ++i) { DIR[i] = moveToEdge(i); } int left = 0, right = INF; for (int i=0; i<D; ++i) { if (DIR[i] == 1) right = MIN(right, ABS(R - POS[i])); else if (DIR[i] == -1) right = MIN(right, POS[i]); } if (right == INF) right = left; while (left != right) { int mid = (left + right) / 2; checkVector(mid); if (checkVector(mid + 1)) left = mid+1; else right = mid; } for (int i=0; i<D; ++i) POS[i] += left * DIR[i]; if (D != 1 && R%2 == 1) { for (int i=0; i<D; ++i) { int rel_down = dimPosRelation(i, POS[i] - 1); int rel_up = dimPosRelation(i, POS[i] + 1); if (rel_down == LESS && rel_up == GREATER){ POS[i] -= 1; break; } else if (rel_down == EQUAL && rel_up == EQUAL) continue; else if (rel_down == EQUAL && rel_up == GREATER){ POS[i] -= 1; continue; } else if (rel_down == GREATER && rel_up == LESS){ POS[i] += 1; break; } else if (rel_down == GREATER && rel_up == EQUAL){ POS[i] += 1; continue; } else if (rel_down == GREATER && rel_up == GREATER) break; } } znalazlem(POS); }
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 | #include "cielib.h" #define ABS(x) ((x)<0 ? -(x) : (x)) #define MIN(x, y) ((x)<(y) ? (x) : (y)) #define GREATER (int)1 #define EQUAL (int)0 #define LESS (int)(-1) #define INF 1000000005 #define DEBUG true int D, R, K, POS[505]; int DIR[505]; bool check(){ return czyCieplo(POS); } int dimPosRelation(int dim, int pos) { if (pos < 0 || pos > R) return 1; int originPos = POS[dim]; POS[dim] = pos; bool rel_1 = check(); POS[dim] = originPos; bool rel_2 = check(); if (rel_1) return LESS; if (rel_2) return GREATER; return EQUAL; } bool checkVector(int factor) { int MOVED_POS[505]; for (int i=0; i<D; ++i) MOVED_POS[i] = POS[i] + DIR[i] * factor; return czyCieplo(MOVED_POS); } int moveToEdge(int dim){ int rel_down = dimPosRelation(dim, POS[dim] - 1); int rel_up = dimPosRelation(dim, POS[dim] + 1); if (rel_down == GREATER && rel_up == GREATER) return EQUAL; if (rel_down == GREATER) return GREATER; if (rel_up == GREATER) return LESS; if (rel_down == EQUAL && rel_up == EQUAL){ rel_down = dimPosRelation(dim, 0); rel_up = dimPosRelation(dim, R); if (rel_down == EQUAL && rel_up == EQUAL) return EQUAL; int result; int boundPos; if (rel_down == GREATER){ boundPos = 0; result = GREATER; } else { boundPos = R; result = LESS; } while (POS[dim] != boundPos-1 && POS[dim] != boundPos+1){ int midPos = (boundPos + POS[dim]) / 2; if (dimPosRelation(dim, midPos) == EQUAL) POS[dim] = midPos; else boundPos = midPos; } return result; } } int main() { D = podajD(); K = podajK(); R = podajR(); for (int i=0; i<D; ++i) POS[i] = R / 2; check(); for (int i=0; i<D; ++i) { DIR[i] = moveToEdge(i); } int left = 0, right = INF; for (int i=0; i<D; ++i) { if (DIR[i] == 1) right = MIN(right, ABS(R - POS[i])); else if (DIR[i] == -1) right = MIN(right, POS[i]); } if (right == INF) right = left; while (left != right) { int mid = (left + right) / 2; checkVector(mid); if (checkVector(mid + 1)) left = mid+1; else right = mid; } for (int i=0; i<D; ++i) POS[i] += left * DIR[i]; if (D != 1 && R%2 == 1) { for (int i=0; i<D; ++i) { int rel_down = dimPosRelation(i, POS[i] - 1); int rel_up = dimPosRelation(i, POS[i] + 1); if (rel_down == LESS && rel_up == GREATER){ POS[i] -= 1; break; } else if (rel_down == EQUAL && rel_up == EQUAL) continue; else if (rel_down == EQUAL && rel_up == GREATER){ POS[i] -= 1; continue; } else if (rel_down == GREATER && rel_up == LESS){ POS[i] += 1; break; } else if (rel_down == GREATER && rel_up == EQUAL){ POS[i] += 1; continue; } else if (rel_down == GREATER && rel_up == GREATER) break; } } znalazlem(POS); } |