답안 #551692

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
551692 2022-04-21T10:48:43 Z elazarkoren 저울 (IOI15_scales) C++17
100 / 100
202 ms 1964 KB
#include <bits/stdc++.h>
#include "scales.h"
#define x first
#define y second
#define all(v) v.begin(), v.end()
#define chkmin(a, b) a = min(a, b)
#define chkmax(a, b) a = max(a, b)
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vii;

const ll A = 9e8;
const int mod = 1e9 + 9;

int Hash(vi &v) {
    ll ans = 0;
    for (int x : v) {
        ans = (ans * A % mod + x + 1) % mod;
    }
    return ans;
}

map<int, vi> startegy_tree;
//type 1 = light,
//     2 = heavy,
//     3 = med,
//     4 = next

vvi all_per;

bool Solve(vi &permutations, int x) {
    if (permutations.size() <= 1) return true;
    int log3 = 0;
    int n = permutations.size();
    for (int i = 1; i < n; i *= 3, log3++);
    if (x + log3 > 6) return false;
    int hash = Hash(permutations);
    if (startegy_tree.count(hash)) return true;
    for (int a = 1; a <= 6; a++) {
        for (int b = a + 1; b <= 6; b++) {
            for (int c = b + 1; c <= 6; c++) {
                vi v1, v2, v3;
                for (int y : permutations) {
                    auto &v = all_per[y];
                    int ind1, ind2, ind3;
                    for (ind1 = 0; v[ind1] != a; ind1++);
                    for (ind2 = 0; v[ind2] != b; ind2++);
                    for (ind3 = 0; v[ind3] != c; ind3++);
                    int i = max({ind1, ind2, ind3}), j = min({ind1, ind2, ind3});
                    if (i != ind1 && j != ind1) v1.push_back(y);
                    else if (i != ind2 && j != ind2) v2.push_back(y);
                    else v3.push_back(y);
                }
                if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) {
                    startegy_tree[hash] = {a, b, c, 3};
                    return true;
                }
            }
        }
    }
    for (int a = 1; a <= 6; a++) {
        for (int b = a + 1; b <= 6; b++) {
            for (int c = b + 1; c <= 6; c++) {
                for (int d = 1; d <= 6; d++) {
                    if (d == a || d == b || d == c) continue;
                    vi v1, v2, v3;
                    for (int y : permutations) {
                        auto &v = all_per[y];
                        int ind;
                        for (ind = 0; v[ind] != d; ind++);
                        for (; v[ind] != a && v[ind] != b && v[ind] != c; ind++, ind %= 6);
                        if (v[ind] == a) v1.push_back(y);
                        else if (v[ind] == b) v2.push_back(y);
                        else v3.push_back(y);
                    }
                    if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) {
                        startegy_tree[hash] = {a, b, c, d, 4};
                        return true;
                    }
                }
            }
        }
    }
    for (int a = 1; a <= 6; a++) {
        for (int b = a + 1; b <= 6; b++) {
            for (int c = b + 1; c <= 6; c++) {
                vi v1, v2, v3;
                for (int y : permutations) {
                    auto &v = all_per[y];
                    int ind1, ind2, ind3;
                    for (ind1 = 0; v[ind1] != a; ind1++);
                    for (ind2 = 0; v[ind2] != b; ind2++);
                    for (ind3 = 0; v[ind3] != c; ind3++);
                    int i = min({ind1, ind2, ind3});
                    if (i == ind1) v1.push_back(y);
                    else if (i == ind2) v2.push_back(y);
                    else v3.push_back(y);
                }
                if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) {
                    startegy_tree[hash] = {a, b, c, 1};
                    return true;
                }
            }
        }
    }
    for (int a = 1; a <= 6; a++) {
        for (int b = a + 1; b <= 6; b++) {
            for (int c = b + 1; c <= 6; c++) {
                vi v1, v2, v3;
                for (int y : permutations) {
                    auto &v = all_per[y];
                    int ind1, ind2, ind3;
                    for (ind1 = 0; v[ind1] != a; ind1++);
                    for (ind2 = 0; v[ind2] != b; ind2++);
                    for (ind3 = 0; v[ind3] != c; ind3++);
                    int i = max({ind1, ind2, ind3});
                    if (i == ind1) v1.push_back(y);
                    else if (i == ind2) v2.push_back(y);
                    else v3.push_back(y);
                }
                if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) {
                    startegy_tree[hash] = {a, b, c, 2};
                    return true;
                }
            }
        }
    }
    return false;
}

void init(int T) {
    vi permutations(720);
    iota(all(permutations), 0);
    vi v = {1, 2, 3, 4, 5, 6};
    do {
        all_per.push_back(v);
    } while (next_permutation(all(v)));
    Solve(permutations, 0);
}

map<vi, int> asksLight;
int queryLight(int a, int b, int c) {
    vi v = {a, b, c};
    sort(all(v));
    if (asksLight.count(v)) return asksLight[v];
    return asksLight[v] = getLightest(a, b, c);
}

map<vi, int> asksHeavy;
int queryHeavy(int a, int b, int c) {
    vi v = {a, b, c};
    sort(all(v));
    if (asksHeavy.count(v)) return asksHeavy[v];
    return asksHeavy[v] = getHeaviest(a, b, c);
}

map<vi, int> asksMed;
int queryMed(int a, int b, int c) {
    vi v = {a, b, c};
    sort(all(v));
    if (asksMed.count(v)) return asksMed[v];
    return asksMed[v] = getMedian(a, b, c);
}

map<vi, int> asksNext;
int queryNext(int a, int b, int c, int d) {
    vi v = {a, b, c};
    sort(all(v));
    v.push_back(d);
    if (asksNext.count(v)) return asksNext[v];
    return asksNext[v] = getNextLightest(a, b, c, d);
}

void orderCoins() {
    int w[] = {1, 2, 3, 4, 5, 6};
    asksLight.clear();
    asksHeavy.clear();
    asksMed.clear();
    asksNext.clear();
    vi permutations(720);
    iota(all(permutations), 0);
    vi cnt_type(5);
    while (permutations.size() > 1) {
        int hash = Hash(permutations);
        vi v = startegy_tree[hash];
        int type = v.back();
        cnt_type[type]++;
        int a = v[0], b = v[1], c = v[2];
        vi next;
        next.reserve(permutations.size() / 3);
        if (type == 1) {
            int x = queryLight(a, b, c);
            for (int y : permutations) {
                vi &v = all_per[y];
                int ind1, ind2, ind3;
                for (ind1 = 0; v[ind1] != a; ind1++);
                for (ind2 = 0; v[ind2] != b; ind2++);
                for (ind3 = 0; v[ind3] != c; ind3++);
                if (v[min({ind1, ind2, ind3})] == x) next.push_back(y);
            }
        } else if (type == 2) {
            int x = queryHeavy(a, b, c);
            for (int y : permutations) {
                vi &v = all_per[y];
                int ind1, ind2, ind3;
                for (ind1 = 0; v[ind1] != a; ind1++);
                for (ind2 = 0; v[ind2] != b; ind2++);
                for (ind3 = 0; v[ind3] != c; ind3++);
                if (v[max({ind1, ind2, ind3})] == x) next.push_back(y);
            }
        } else if (type == 3) {
            int x = queryMed(a, b, c);
            if (x == b) swap(a, b);
            if (x == c) swap(a, c);
            for (int y : permutations) {
                vi &v = all_per[y];
                int ind1, ind2, ind3;
                for (ind1 = 0; v[ind1] != a; ind1++);
                for (ind2 = 0; v[ind2] != b; ind2++);
                for (ind3 = 0; v[ind3] != c; ind3++);
                if (ind1 != max({ind1, ind2, ind3}) && ind1 != min({ind1, ind2, ind3})) next.push_back(y);
            }
        } else {
            int d = v[3];
            int x = queryNext(a, b, c, d);
            for (int y : permutations) {
                vi &v = all_per[y];
                int ind;
                for (ind = 0; v[ind] != d; ind++);
                for (; v[ind] != a && v[ind] != b && v[ind] != c; ind++, ind %= 6);
                if (v[ind] == x) next.push_back(y);
            }
        }
        swap(permutations, next);
    }
//    cout << cnt_type[1] << ' ' << cnt_type[2] << ' ' << cnt_type[3] << ' ' << cnt_type[4] << '\n';
    vi v = all_per[permutations[0]];
    for (int i = 0; i < 6; i++) w[i] = v[i];
    answer(w);
}

Compilation message

scales.cpp: In function 'int Hash(vi&)':
scales.cpp:23:12: warning: conversion from 'll' {aka 'long long int'} to 'int' may change value [-Wconversion]
   23 |     return ans;
      |            ^~~
scales.cpp: In function 'bool Solve(vi&, int)':
scales.cpp:37:30: warning: conversion from 'std::vector<int>::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
   37 |     int n = permutations.size();
      |             ~~~~~~~~~~~~~~~~~^~
scales.cpp: In function 'void init(int)':
scales.cpp:134:15: warning: unused parameter 'T' [-Wunused-parameter]
  134 | void init(int T) {
      |           ~~~~^
scales.cpp: In function 'void orderCoins()':
scales.cpp:197:21: warning: declaration of 'v' shadows a previous local [-Wshadow]
  197 |                 vi &v = all_per[y];
      |                     ^
scales.cpp:188:12: note: shadowed declaration is here
  188 |         vi v = startegy_tree[hash];
      |            ^
scales.cpp:207:21: warning: declaration of 'v' shadows a previous local [-Wshadow]
  207 |                 vi &v = all_per[y];
      |                     ^
scales.cpp:188:12: note: shadowed declaration is here
  188 |         vi v = startegy_tree[hash];
      |            ^
scales.cpp:219:21: warning: declaration of 'v' shadows a previous local [-Wshadow]
  219 |                 vi &v = all_per[y];
      |                     ^
scales.cpp:188:12: note: shadowed declaration is here
  188 |         vi v = startegy_tree[hash];
      |            ^
scales.cpp:230:21: warning: declaration of 'v' shadows a previous local [-Wshadow]
  230 |                 vi &v = all_per[y];
      |                     ^
scales.cpp:188:12: note: shadowed declaration is here
  188 |         vi v = startegy_tree[hash];
      |            ^
# 결과 실행 시간 메모리 Grader output
1 Correct 191 ms 1708 KB Output is correct
2 Correct 191 ms 1708 KB Output is correct
3 Correct 189 ms 1740 KB Output is correct
4 Correct 189 ms 1712 KB Output is correct
5 Correct 195 ms 1908 KB Output is correct
6 Correct 192 ms 1712 KB Output is correct
7 Correct 194 ms 1740 KB Output is correct
8 Correct 192 ms 1920 KB Output is correct
9 Correct 190 ms 1904 KB Output is correct
10 Correct 190 ms 1748 KB Output is correct
11 Correct 194 ms 1724 KB Output is correct
12 Correct 189 ms 1732 KB Output is correct
13 Correct 188 ms 1740 KB Output is correct
14 Correct 188 ms 1756 KB Output is correct
15 Correct 195 ms 1796 KB Output is correct
16 Correct 201 ms 1764 KB Output is correct
17 Correct 195 ms 1740 KB Output is correct
18 Correct 193 ms 1792 KB Output is correct
19 Correct 195 ms 1860 KB Output is correct
20 Correct 189 ms 1768 KB Output is correct
21 Correct 190 ms 1740 KB Output is correct
22 Correct 188 ms 1860 KB Output is correct
23 Correct 187 ms 1812 KB Output is correct
24 Correct 191 ms 1880 KB Output is correct
25 Correct 194 ms 1744 KB Output is correct
26 Correct 193 ms 1772 KB Output is correct
27 Correct 188 ms 1736 KB Output is correct
28 Correct 195 ms 1868 KB Output is correct
29 Correct 194 ms 1788 KB Output is correct
30 Correct 190 ms 1880 KB Output is correct
31 Correct 193 ms 1768 KB Output is correct
32 Correct 202 ms 1736 KB Output is correct
33 Correct 191 ms 1744 KB Output is correct
34 Correct 188 ms 1844 KB Output is correct
35 Correct 193 ms 1740 KB Output is correct
36 Correct 189 ms 1824 KB Output is correct
37 Correct 189 ms 1792 KB Output is correct
38 Correct 195 ms 1876 KB Output is correct
39 Correct 191 ms 1780 KB Output is correct
40 Correct 189 ms 1964 KB Output is correct