# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
102632 | wxh010910 | 저울 (IOI15_scales) | C++17 | 334 ms | 16816 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#include "scales.h"
using namespace std;
const int N = 6;
const int M = 720;
const int S = 5184;
const vector<int> p3 = {1, 3, 9, 27, 81, 243, 729};
vector<vector<int>> value(M, vector<int>(S, -1));
map<pair<vector<int>, int>, int> tree;
vector<vector<int>> all(M);
vector<bool> valid(S);
vector<int> choices;
bool dfs(vector<int> remain, int depth) {
if ((int) remain.size() > p3[depth]) {
return false;
}
if ((int) remain.size() == 1) {
return true;
}
if (tree.count(make_pair(remain, depth))) {
return tree[make_pair(remain, depth)] != -1;
}
for (auto p : choices) {
vector<vector<int>> partition(N);
for (auto i : remain) {
partition[value[i][p]].push_back(i);
}
bool ok = true;
for (int i = 0; i < N; ++i) {
if (!partition[i].empty() && !dfs(partition[i], depth - 1)) {
ok = false;
break;
}
}
if (ok) {
tree[make_pair(remain, depth)] = p;
return true;
}
}
tree[make_pair(remain, depth)] = -1;
return false;
}
void go(vector<int> remain, int depth) {
if ((int) remain.size() == 1) {
int* ans = new int[N];
for (int i = 0; i < N; ++i) {
ans[all[remain[0]][i]] = i + 1;
}
answer(ans);
return;
}
int code = tree[make_pair(remain, depth)];
int type = code / 1296;
int a = code / 216 % 6;
int b = code / 36 % 6;
int c = code / 6 % 6;
int d = code % 6;
int res;
if (type == 0) {
res = getHeaviest(a + 1, b + 1, c + 1) - 1;
} else if (type == 1) {
res = getLightest(a + 1, b + 1, c + 1) - 1;
} else if (type == 2) {
res = getMedian(a + 1, b + 1, c + 1) - 1;
} else {
res = getNextLightest(a + 1, b + 1, c + 1, d + 1) - 1;
}
vector<int> new_remain;
for (auto i : remain) {
if (value[i][code] == res) {
new_remain.push_back(i);
}
}
go(new_remain, depth - 1);
}
void init(int T) {
vector<int> p(N);
for (int i = 0; i < N; ++i) {
p[i] = i;
}
for (int i = 0; i < 3; ++i) {
for (int a = 0; a < N; ++a) {
for (int b = a + 1; b < N; ++b) {
for (int c = b + 1; c < N; ++c) {
valid[i * 1296 + a * 216 + b * 36 + c * 6 + 0] = true;
}
}
}
}
for (int a = 0; a < N; ++a) {
for (int b = a + 1; b < N; ++b) {
for (int c = b + 1; c < N; ++c) {
for (int d = 0; d < N; ++d) {
if (d == a || d == b || d == c) {
continue;
}
valid[3 * 1296 + a * 216 + b * 36 + c * 6 + d] = true;
}
}
}
}
for (int i = 0; i < S; ++i) {
if (valid[i]) {
choices.push_back(i);
}
}
for (int ptr = 0; ptr < M; ++ptr) {
all[ptr] = p;
for (int a = 0; a < N; ++a) {
for (int b = a + 1; b < N; ++b) {
for (int c = b + 1; c < N; ++c) {
vector<int> seq = {a, b, c};
sort(seq.begin(), seq.end(), [&](const int &x, const int &y) {
return p[x] < p[y];
});
value[ptr][0 * 1296 + a * 216 + b * 36 + c * 6 + 0] = seq[2];
value[ptr][1 * 1296 + a * 216 + b * 36 + c * 6 + 0] = seq[0];
value[ptr][2 * 1296 + a * 216 + b * 36 + c * 6 + 0] = seq[1];
for (int d = 0; d < N; ++d) {
if (d == a || d == b || d == c) {
continue;
}
if (p[d] > p[seq[2]]) {
value[ptr][3 * 1296 + a * 216 + b * 36 + c * 6 + d] = seq[0];
} else {
for (int i = 0; i < 3; ++i) {
if (p[seq[i]] > p[d]) {
value[ptr][3 * 1296 + a * 216 + b * 36 + c * 6 + d] = seq[i];
break;
}
}
}
}
}
}
}
next_permutation(p.begin(), p.end());
}
vector<int> remain(M);
for (int i = 0; i < M; ++i) {
remain[i] = i;
}
dfs(remain, 6);
}
void orderCoins() {
vector<int> remain(M);
for (int i = 0; i < M; ++i) {
remain[i] = i;
}
go(remain, 6);
}
컴파일 시 표준 에러 (stderr) 메시지
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |