# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
662873 | BlancaHM | 커다란 상품 (IOI17_prize) | C++14 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "prize.h"
#include <vector>
using namespace std;
vector<pair<int, int>> preguntasHechas;
int totalInteresantes;
vector<int> preguntar(int i) {
if (preguntasHechas[i].first == -1) {
auto a = ask(i);
preguntasHechas[i] = make_pair(a[0], a[1]);
}
return preguntasHechas[i];
}
int carosIzq(int i) {
vector<int> v = preguntar(i);
return v.first;
}
int carosDer(int i) {
vector<int> v = preguntar(i);
return v.second;
}
// limIzq contendrá lollipop
// buscamos el diamante en [limIzq, limDer]
// sabemos que en el intervalo hay numPremiosCaros (i.e. premios no lollipop)
int buscarDiamanteEnIntervalo(int limIzq, int limDer, int numPremiosCaros) {
if (!numPremiosCaros) return -1;
if (limDer-limIzq == numPremiosCaros) {
// todas las posiciones aparte de limIzq contienen premio caro -> buscamos una a una por el diamante
for (int i = limIzq+1; i <= limDer; i++) {
preguntar(i);
if (carosIzq(i) + carosDer(i) == 0) {
return i;
}
}
return -1;
}
int mid = limIzq + (limDer-limIzq)/2;
int pos = mid;
while(pos <= limDer) {
if (carosIzq(pos) + carosDer(pos) == 0) {
return pos;
}
if (carosIzq(pos) + carosDer(pos) == totalInteresantes) {
break;
}
pos++;
}
if (pos == limDer+1) {
// no hay lollipops en [mid, limDer]
return buscarDiamanteEnIntervalo(limIzq, mid-1, numPremiosCaros - (numDer - mid + 1));
} else {
int diamante = buscarDiamanteEnIntervalo(limIzq, mid-1, carosIzq(pos) - carosIzq(limIzq) + mid - pos);
if (diamante != -1) return diamante;
return buscarDiamanteEnIntervalo(pos, limDer, q - carosIzq(pos) + carosIzq(limIzq));
}
}
int find_best(int n) {
preguntasHechas.assign(n, make_pair(-1, -1));
// buscamos el índice del primer lollipop
int primerLollipop = 0;
totalInteresantes = -1;
for (int i = 0; i <= min(473, n-1); i++) {
if (carosIzq(i) + carosDer(i) == 0) return i;
if (carosIzq(i) + carosDer(i) > totalInteresantes) {
primerLollipop = i;
totalInteresantes = carosIzq(i) + carosDer(i);
if (totalInteresantes >= 40) break;
}
}
return buscarDiamanteEnIntervalo(primerLollipop, n-1, carosDer(primerLollipop));
}