# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
725810 | becaido | 저울 (IOI15_scales) | C++17 | 7 ms | 372 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx,popcnt,sse4,abm")
#include <bits/stdc++.h>
using namespace std;
#ifndef WAIMAI
#include "scales.h"
#endif
#ifdef WAIMAI
#define debug(HEHE...) cout << "[" << #HEHE << "] : ", dout(HEHE)
void dout() {cout << '\n';}
template<typename T, typename...U>
void dout (T t, U...u) {cout << t << (sizeof... (u) ? ", " : ""), dout (u...);}
#else
#define debug(...) 7122
#endif
#define ll long long
#define Waimai ios::sync_with_stdio(false), cin.tie(0)
#define FOR(x,a,b) for (int x = a, I = b; x <= I; x++)
#define pb emplace_back
#define F first
#define S second
#ifdef WAIMAI
#define _MAXN 6
#define _MAX_ANSWER_CALLS 1
static int _realC[_MAXN];
static int _ind[_MAXN];
static int _numQueries;
static int _numAnswerCalls;
static int _getNumberOfTests() {
int T;
cin >> T;
return T;
}
static void _initNewTest() {
int i, ret;
for (i = 0; i < _MAXN; i++) {
cin >> _realC[i];
_realC[i]--;
_ind[_realC[i]] = i;
}
_numQueries = 0;
_numAnswerCalls = 0;
}
void answer(int W[]) {
int i;
_numAnswerCalls++;
if (_numAnswerCalls > _MAX_ANSWER_CALLS)
return;
for (i = 0; i < 6; i++) cout << W[i] << ' ';
cout << "\n" << _numQueries << '\n';
}
static void _checkQuery(int A, int B, int C, int D) {
if (D == -1) {
if (A < 1 || A > 6 || B < 1 || B > 6 || C < 1 || C > 6)
assert(0);
if (A == B || B == C || A == C)
assert(0);
}
else {
if (A < 1 || A > 6 || B < 1 || B > 6 || C < 1 || C > 6 || D < 1 || D > 6)
assert(0);
if (A == B || A == C || A == D || B == C || B == D || C == D)
assert(0);
}
}
int getMedian(int A, int B, int C) {
_numQueries++;
_checkQuery(A, B, C, -1);
A--; B--; C--;
if (_ind[B] < _ind[A] && _ind[A] < _ind[C])
return A + 1;
if (_ind[C] < _ind[A] && _ind[A] < _ind[B])
return A + 1;
if (_ind[A] < _ind[B] && _ind[B] < _ind[C])
return B + 1;
if (_ind[C] < _ind[B] && _ind[B] < _ind[A])
return B + 1;
return C + 1;
}
int getHeaviest(int A, int B, int C) {
_numQueries++;
_checkQuery(A, B, C, -1);
A--; B--; C--;
if (_ind[A] > _ind[B] && _ind[A] > _ind[C])
return A + 1;
if (_ind[B] > _ind[A] && _ind[B] > _ind[C])
return B + 1;
return C + 1;
}
int getLightest(int A, int B, int C) {
_numQueries++;
_checkQuery(A, B, C, -1);
A--; B--; C--;
if (_ind[A] < _ind[B] && _ind[A] < _ind[C])
return A + 1;
if (_ind[B] < _ind[A] && _ind[B] < _ind[C])
return B + 1;
return C + 1;
}
int getNextLightest(int A, int B, int C, int D) {
int allLess = 1;
_numQueries++;
_checkQuery(A, B, C, D);
A--; B--; C--; D--;
if (_ind[A] > _ind[D] || _ind[B] > _ind[D] || _ind[C] > _ind[D])
allLess = 0;
if (allLess == 1) {
if (_ind[A] < _ind[B] && _ind[A] < _ind[C])
return A + 1;
if (_ind[B] < _ind[A] && _ind[B] < _ind[C])
return B + 1;
return C + 1;
}
if (_ind[A] > _ind[D]) {
if ((_ind[A] < _ind[B] || _ind[B] < _ind[D]) && (_ind[A] < _ind[C] || _ind[C] < _ind[D]))
return A + 1;
}
if (_ind[B] > _ind[D]) {
if ((_ind[B] < _ind[A] || _ind[A] < _ind[D]) && (_ind[B] < _ind[C] || _ind[C] < _ind[D]))
return B + 1;
}
return C + 1;
}
#endif
const int MAX = 720;
array<int, 6> P[MAX];
int pos[MAX][7];
struct Tree {
int ty, a, b, c, d;
Tree *nxt[3];
Tree() {}
Tree(int ty, int a, int b, int c, int d = 0) : ty(ty), a(a), b(b), c(c), d(d) {}
tuple<int, int, int, int, int> id() {
return {ty, a, b, c, d};
}
};
Tree *root;
bool build(Tree *&t, vector<int> cur, int lim) {
if (cur.size() <= 1) return 1;
t = new Tree();
FOR (ty, 1, 3) FOR (i, 1, 6) FOR (j, i + 1, 6) FOR (k, j + 1, 6) {
*t = Tree(ty, i, j, k);
vector<int> vi, vj, vk;
bool f = 1;
for (int id : cur) {
int cp;
if (ty == 1) cp = min({pos[id][i], pos[id][j], pos[id][k]});
if (ty == 2) cp = max({pos[id][i], pos[id][j], pos[id][k]});
if (ty == 3) cp = pos[id][i] + pos[id][j] + pos[id][k] - min({pos[id][i], pos[id][j], pos[id][k]}) - max({pos[id][i], pos[id][j], pos[id][k]});
(pos[id][i] == cp ? vi : pos[id][j] == cp ? vj : vk).pb(id);
if (max({vi.size(), vj.size(), vk.size()}) > lim) {
f = 0;
break;
}
}
if (f) f &= build(t->nxt[0], vi, lim / 3);
if (f) f &= build(t->nxt[1], vj, lim / 3);
if (f) f &= build(t->nxt[2], vk, lim / 3);
if (f) return 1;
}
FOR (d, 1, 6) FOR (i, 1, 6) if (i != d) FOR (j, i + 1, 6) if (j != d) FOR (k, j + 1, 6) if (k != d) {
*t = Tree(4, i, j, k, d);
vector<int> vi, vj, vk;
bool f = 1;
for (int id : cur) {
int pi = pos[id][i], pj = pos[id][j], pk = pos[id][k], pd = pos[id][d], cp = 6;
for (int xp : {pi, pj, pk}) if (xp > pd) cp = min(cp, xp);
if (cp == 6) cp = min({pi, pj, pk});
(pos[id][i] == cp ? vi : pos[id][j] == cp ? vj : vk).pb(id);
if (max({vi.size(), vj.size(), vk.size()}) > lim) {
f = 0;
break;
}
}
if (f) f &= build(t->nxt[0], vi, lim / 3);
if (f) f &= build(t->nxt[1], vj, lim / 3);
if (f) f &= build(t->nxt[2], vk, lim / 3);
if (f) return 1;
}
delete(t);
return 0;
}
void init(int T) {
array<int, 6> a;
iota(a.begin(), a.end(), 1);
FOR (i, 0, MAX - 1) {
P[i] = a;
FOR (j, 0, 5) pos[i][a[j]] = j;
next_permutation(a.begin(), a.end());
}
vector<int> all(MAX);
iota(all.begin(), all.end(), 0);
build(root, all, 243);
}
void orderCoins() {
vector<int> all(MAX);
iota(all.begin(), all.end(), 0);
Tree *cur = root;
while (all.size() > 1) {
int result;
auto [ty, a, b, c, d] = cur->id();
if (ty == 1) result = getLightest(a, b, c);
if (ty == 2) result = getHeaviest(a, b, c);
if (ty == 3) result = getMedian(a, b, c);
if (ty == 4) result = getNextLightest(a, b, c, d);
vector<int> tmp;
for (int id : all) {
int pi = pos[id][a], pj = pos[id][b], pk = pos[id][c];
if (ty == 1 && min({pi, pj, pk}) == pos[id][result]) tmp.pb(id);
if (ty == 2 && max({pi, pj, pk}) == pos[id][result]) tmp.pb(id);
if (ty == 3 && pi + pj + pk - min({pi, pj, pk}) - max({pi, pj, pk}) == pos[id][result]) tmp.pb(id);
if (ty == 4) {
int mn = 6;
for (int xp : {pi, pj, pk}) if (xp > pos[id][d]) mn = min(mn, xp);
if (mn == 6) mn = min({pi, pj, pk});
if (mn == pos[id][result]) tmp.pb(id);
}
}
all = tmp;
cur = (result == a ? cur->nxt[0] : result == b ? cur->nxt[1] : cur->nxt[2]);
}
int ans[6];
FOR (i, 0, 5) ans[i] = P[all[0]][i];
answer(ans);
}
#ifdef WAIMAI
int main() {
int T, i;
T = _getNumberOfTests();
init(T);
for (i = 1; i <= T; i++) {
_initNewTest();
orderCoins();
}
return 0;
}
#endif
컴파일 시 표준 에러 (stderr) 메시지
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |