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
#include "cielib.h"

int d, k, r;
int kCalls;
int pozycja[500];
int left[500];
int right[500];
int kierunek[500];
bool fixed[500];
bool wszystkieUstalone;
bool ustalilSie;
int maxSkok;

inline int czyCieploJest(int pozycja[]) {
    if (kCalls < k) {
        kCalls++;
        return czyCieplo(pozycja);
    }
    return 0;
}

inline void skokPrawo(int wymiar, int przedskok) {
    if (przedskok != 0) wszystkieUstalone = false;
    if (right[wymiar] - pozycja[wymiar] + przedskok > maxSkok) right[wymiar] = pozycja[wymiar] - przedskok + maxSkok;
    if (pozycja[wymiar] == right[wymiar]) {  //znalezlismy
        if (maxSkok > przedskok) maxSkok = przedskok;
        fixed[wymiar] = true;
        ustalilSie = true;
    } else {
        left[wymiar] = pozycja[wymiar];
        int zasieg = right[wymiar] - left[wymiar] + przedskok;
        if (maxSkok > zasieg) maxSkok = zasieg;
        pozycja[wymiar] = (left[wymiar] + right[wymiar] + 1) / 2;
        czyCieploJest(pozycja);
        ustalilSie = false;
        wszystkieUstalone = false;
    }
}

inline void skokLewo(int wymiar, int przedskok) {
    if (przedskok != 0) wszystkieUstalone = false;
    if (pozycja[wymiar] - left[wymiar] + przedskok > maxSkok) left[wymiar] = pozycja[wymiar] + przedskok - maxSkok;
    if (pozycja[wymiar] == left[wymiar]) {  //znalezlismy
        if (maxSkok > przedskok) maxSkok = przedskok;
        fixed[wymiar] = true;
        ustalilSie = true;
    } else {
        right[wymiar] = pozycja[wymiar];
        int zasieg = right[wymiar] - left[wymiar] + przedskok;
        if (maxSkok > zasieg) maxSkok = zasieg;
        pozycja[wymiar] = (left[wymiar] + right[wymiar] + 1) / 2;
        czyCieploJest(pozycja);
        ustalilSie = false;
        wszystkieUstalone = false;
    }
}

int main(int argc, char *argv[]) {
    d = podajD();
    k = podajK();
    r = podajR();
    kCalls = 0;
    
    for (int i = 0; i < d; i++) {
        pozycja[i] = r / 2;
        left[i] = 0;
        right[i] = r;
        fixed[i] = false;
    }
    maxSkok = r;
    czyCieploJest(pozycja);
    
    wszystkieUstalone = false;
    //petla zewnetrzna
    while (!wszystkieUstalone && kCalls < k) {
        wszystkieUstalone = true;
        //szukaj wymiaru
        int wymiar = 0;
        int niezdecydowany = 0;
        while (wymiar < d && kCalls < k) {
            kierunek[wymiar] = 0;
            if (!fixed[wymiar]) {   // ten wymiar jeszcze nie zostal ustalony
                ustalilSie = false;
                while (!ustalilSie && kCalls < k) {
                    ustalilSie = true;
                    if (pozycja[wymiar] < right[wymiar]) {  //mozna w prawo
                        pozycja[wymiar] += 1;
                        if (czyCieploJest(pozycja)) {   //w prawo jest blizej i jestesmy jedynym najdalszym
                            skokPrawo(wymiar, 1);
                        } else if (pozycja[wymiar] > left[wymiar] + 1) {   //mozna wrocic i w lewo
                            pozycja[wymiar] -= 2;
                            if (czyCieploJest(pozycja)) {   //w lewo jest blizej i nie  wiadomo czy jestesmy jedynym najdalszym
                                skokLewo(wymiar, 1);
                            } else {    //wracamy do punktu wyjscia
                                pozycja[wymiar] += 1;
                                if (czyCieploJest(pozycja)) {   //w prawo jest blizej i nie jestesmy jedynym najdalszym ALBO jestesmy u celu
                                    skokPrawo(wymiar, 0);   //??? co jak u celu
                                }
                            }
                        } else {    //wracamy do punktu wyjscia
                            pozycja[wymiar] -= 1;
                            if (czyCieploJest(pozycja)) {   //w lewo jest blizej, ale jestesmy na krawedzi zakresu, wiec jestesmy u celu
                                fixed[wymiar] = true;
                                ustalilSie = true;
                            } else {
                                niezdecydowany++;
                                kierunek[wymiar] = 1;
                            }
                        }
                    } else if (pozycja[wymiar] > left[wymiar]) {    //jestesmy na prawej krawedzi zakresu i mozna w lewo
                        pozycja[wymiar] -= 1;
                        if (czyCieploJest(pozycja)) {  //w lewo jest blizej
                            skokLewo(wymiar, 1);
                        } else {  //wracamy do punktu wyjscia
                            pozycja[wymiar] += 1;
                            if (czyCieploJest(pozycja)) {  //w prawo jest blizej, ale jestemy na krawedzi zakresu, wiec jestesmy u celu
                                fixed[wymiar] = true;
                                ustalilSie = true;
                            } else {
                                niezdecydowany++;
                                kierunek[wymiar] = -1;
                            }
                        }
                    } else {
                        fixed[wymiar] = true;
                        ustalilSie = true;
                    }
                }
            }
            wymiar++;
        }
        if (wszystkieUstalone && niezdecydowany > 0) {
            for (int i = 0; i < d; i++) {
                if (!fixed[i] && kierunek[i] != 0) {
                    pozycja[i] += kierunek[i];
                }
            }
            wszystkieUstalone = false;
        }
    }
    znalazlem(pozycja);
    return 0;
}