# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1037296 | Zicrus | 저울 (IOI15_scales) | C++17 | 120 ms | 452 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#include "scales.h"
using namespace std;
typedef long long ll;
vector<vector<int>> perms(720);
void init(int T) {
for (int i = 0; i < 720; i++) {
perms[i] = {1, 2, 3, 4, 5, 6};
swap(perms[i][0], perms[i][0 + ((i) % 6)]);
swap(perms[i][1], perms[i][1 + ((i/6) % 5)]);
swap(perms[i][2], perms[i][2 + ((i/6/5) % 4)]);
swap(perms[i][3], perms[i][3 + ((i/6/5/4) % 3)]);
swap(perms[i][4], perms[i][4 + ((i/6/5/4/3) % 2)]);
}
}
int maxPossAfterLow(vector<bool> &poss, int a, int b, int c) {
int mxA = 0, mxB = 0, mxC = 0;
for (int i = 0; i < 720; i++) {
if (!poss[i]) continue;
int idA = find(perms[i].begin(), perms[i].end(), a) - perms[i].begin();
int idB = find(perms[i].begin(), perms[i].end(), b) - perms[i].begin();
int idC = find(perms[i].begin(), perms[i].end(), c) - perms[i].begin();
if (idA < idB && idA < idC) mxA++;
if (idB < idA && idB < idC) mxB++;
if (idC < idB && idC < idA) mxC++;
}
return max({mxA, mxB, mxC});
}
int maxPossAfterMid(vector<bool> &poss, int a, int b, int c) {
int mxA = 0, mxB = 0, mxC = 0;
for (int i = 0; i < 720; i++) {
if (!poss[i]) continue;
int idA = find(perms[i].begin(), perms[i].end(), a) - perms[i].begin();
int idB = find(perms[i].begin(), perms[i].end(), b) - perms[i].begin();
int idC = find(perms[i].begin(), perms[i].end(), c) - perms[i].begin();
if ((idA < idB) != (idA < idC)) mxA++;
if ((idB < idA) != (idB < idC)) mxB++;
if ((idC < idB) != (idC < idA)) mxC++;
}
return max({mxA, mxB, mxC});
}
int maxPossAfterHigh(vector<bool> &poss, int a, int b, int c) {
int mxA = 0, mxB = 0, mxC = 0;
for (int i = 0; i < 720; i++) {
if (!poss[i]) continue;
int idA = find(perms[i].begin(), perms[i].end(), a) - perms[i].begin();
int idB = find(perms[i].begin(), perms[i].end(), b) - perms[i].begin();
int idC = find(perms[i].begin(), perms[i].end(), c) - perms[i].begin();
if (idA > idB && idA > idC) mxA++;
if (idB > idA && idB > idC) mxB++;
if (idC > idB && idC > idA) mxC++;
}
return max({mxA, mxB, mxC});
}
int maxPossAfterD(vector<bool> &poss, int a, int b, int c, int d) {
int mxA = 0, mxB = 0, mxC = 0;
for (int i = 0; i < 720; i++) {
if (!poss[i]) continue;
int idA = find(perms[i].begin(), perms[i].end(), a) - perms[i].begin();
int idB = find(perms[i].begin(), perms[i].end(), b) - perms[i].begin();
int idC = find(perms[i].begin(), perms[i].end(), c) - perms[i].begin();
int idD = find(perms[i].begin(), perms[i].end(), d) - perms[i].begin();
if (idD > idA && idD > idB && idD > idC) {
if (idA < idB && idA < idC) mxA++;
if (idB < idA && idB < idC) mxB++;
if (idC < idB && idC < idA) mxC++;
continue;
}
vector<ll> larger;
if (idA > idD) larger.push_back(idA);
if (idB > idD) larger.push_back(idB);
if (idC > idD) larger.push_back(idC);
ll mn = 6;
for (auto &e : larger) {
mn = min(mn, e);
}
if (mn == idA) mxA++;
if (mn == idB) mxB++;
if (mn == idC) mxC++;
}
return max({mxA, mxB, mxC});
}
void queryLow(vector<bool> &poss, ll &possCnt, int a, int b, int c) {
int t = getLightest(a, b, c);
for (int i = 0; i < 720; i++) {
if (!poss[i]) continue;
int idT = find(perms[i].begin(), perms[i].end(), t) - perms[i].begin();
int idA = find(perms[i].begin(), perms[i].end(), a) - perms[i].begin();
int idB = find(perms[i].begin(), perms[i].end(), b) - perms[i].begin();
int idC = find(perms[i].begin(), perms[i].end(), c) - perms[i].begin();
if (idT > idA || idT > idB || idT > idC) { poss[i] = false; possCnt--; }
}
}
void queryMid(vector<bool> &poss, ll &possCnt, int a, int b, int c) {
int t = getMedian(a, b, c);
for (int i = 0; i < 720; i++) {
if (!poss[i]) continue;
int idT = find(perms[i].begin(), perms[i].end(), t) - perms[i].begin();
int idA = find(perms[i].begin(), perms[i].end(), a) - perms[i].begin();
int idB = find(perms[i].begin(), perms[i].end(), b) - perms[i].begin();
int idC = find(perms[i].begin(), perms[i].end(), c) - perms[i].begin();
if (idT <= idA && idT <= idB && idT <= idC) { poss[i] = false; possCnt--; }
else if (idT >= idA && idT >= idB && idT >= idC) { poss[i] = false; possCnt--; }
}
}
void queryHigh(vector<bool> &poss, ll &possCnt, int a, int b, int c) {
int t = getHeaviest(a, b, c);
for (int i = 0; i < 720; i++) {
if (!poss[i]) continue;
int idT = find(perms[i].begin(), perms[i].end(), t) - perms[i].begin();
int idA = find(perms[i].begin(), perms[i].end(), a) - perms[i].begin();
int idB = find(perms[i].begin(), perms[i].end(), b) - perms[i].begin();
int idC = find(perms[i].begin(), perms[i].end(), c) - perms[i].begin();
if (idT < idA || idT < idB || idT < idC) { poss[i] = false; possCnt--; }
}
}
void queryD(vector<bool> &poss, ll &possCnt, int a, int b, int c, int d) {
int t = getNextLightest(a, b, c, d);
for (int i = 0; i < 720; i++) {
if (!poss[i]) continue;
int idT = find(perms[i].begin(), perms[i].end(), t) - perms[i].begin();
int idA = find(perms[i].begin(), perms[i].end(), a) - perms[i].begin();
int idB = find(perms[i].begin(), perms[i].end(), b) - perms[i].begin();
int idC = find(perms[i].begin(), perms[i].end(), c) - perms[i].begin();
int idD = find(perms[i].begin(), perms[i].end(), d) - perms[i].begin();
if (idD > idA && idD > idB && idD > idC) {
if (idT > idA || idT > idB || idT > idC) { poss[i] = false; possCnt--; }
continue;
}
vector<ll> larger;
if (idA > idD) larger.push_back(idA);
if (idB > idD) larger.push_back(idB);
if (idC > idD) larger.push_back(idC);
ll mn = 6;
for (auto &e : larger) {
mn = min(mn, e);
}
if (mn != idT) { poss[i] = false; possCnt--; };
}
}
void query(vector<bool> &poss, ll &possCnt) {
int mnCnt = 720;
int mnSetting = 0;
int mnA = 1, mnB = 2, mnC = 3, resD = 4;
for (int a = 1; a <= 6; a++) {
for (int b = a+1; b <= 6; b++) {
for (int c = b+1; c <= 6; c++) {
int low = maxPossAfterLow(poss, a, b, c);
int mid = maxPossAfterMid(poss, a, b, c);
int high = maxPossAfterHigh(poss, a, b, c);
int mnD = 720;
int res1D = 0;
for (int d = 1; d <= 6; d++) {
if (d == a || d == b ||d == c) continue;
ll r = maxPossAfterD(poss, a, b, c, d);
if (r < mnD) {
mnD = r;
res1D = d;
}
}
if (low < mnCnt) {
mnCnt = low;
mnSetting = 0;
mnA = a; mnB = b; mnC = c;
}
if (mid < mnCnt) {
mnCnt = mid;
mnSetting = 1;
mnA = a; mnB = b; mnC = c;
}
if (high < mnCnt) {
mnCnt = high;
mnSetting = 2;
mnA = a; mnB = b; mnC = c;
}
if (mnD < mnCnt) {
mnCnt = mnD;
mnSetting = 3;
mnA = a; mnB = b; mnC = c; resD = res1D;
}
}
}
}
if (mnSetting == 0) queryLow(poss, possCnt, mnA, mnB, mnC);
if (mnSetting == 1) queryMid(poss, possCnt, mnA, mnB, mnC);
if (mnSetting == 2) queryHigh(poss, possCnt, mnA, mnB, mnC);
if (mnSetting == 3) queryD(poss, possCnt, mnA, mnB, mnC, resD);
}
void orderCoins() {
vector<bool> poss(720, true);
ll possCnt = 720;
while (possCnt > 1) {
query(poss, possCnt);
}
for (int i = 0; i < 720; i++) {
if (!poss[i]) continue;
int* W = &(perms[i][0]);
answer(W);
}
}
컴파일 시 표준 에러 (stderr) 메시지
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |