Submission #551080

#TimeUsernameProblemLanguageResultExecution timeMemory
551080elazarkoren저울 (IOI15_scales)C++17
0 / 100
1097 ms7128 KiB
#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;

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

bool Solve(vvi &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;
    if (startegy_tree.count(permutations)) 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++) {
                vvi v1, v2, v3;
                for (vi &v : permutations) {
                    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(v);
                    else if (i == ind2) v2.push_back(v);
                    else v3.push_back(v);
                }
                if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) {
                    startegy_tree[permutations] = {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++) {
                vvi v1, v2, v3;
                for (vi &v : permutations) {
                    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(v);
                    else if (i == ind2) v2.push_back(v);
                    else v3.push_back(v);
                }
                if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) {
                    startegy_tree[permutations] = {a, b, c, 2};
                    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++) {
                vvi v1, v2, v3;
                for (vi &v : permutations) {
                    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(v);
                    else if (i != ind2 && j != ind2) v2.push_back(v);
                    else v3.push_back(v);
                }
                if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) {
                    startegy_tree[permutations] = {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;
                    vvi v1, v2, v3;
                    for (vi &v : permutations) {
                        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(v);
                        else if (v[ind] == b) v2.push_back(v);
                        else v3.push_back(v);
                    }
                    if (Solve(v1, x + 1) && Solve(v2, x + 1) && Solve(v3, x + 1)) {
                        startegy_tree[permutations] = {a, b, c, d, 4};
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

void init(int T) {
    vvi permutations;
    vi v = {1, 2, 3, 4, 5, 6};
    do {
        permutations.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();
    vvi permutations;
    permutations.reserve(720);
    vi v = {1, 2, 3, 4, 5, 6};
    do {
        permutations.push_back(v);
    } while (next_permutation(all(v)));
    while (permutations.size() > 1) {
        vi v = startegy_tree[permutations];
        int type = v.back();
        int a = v[0], b = v[1], c = v[2];
        vvi next;
        next.reserve(permutations.size() / 3);
        if (type == 1) {
            int x = queryLight(a, b, c);
            for (vi &v : permutations) {
                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(v);
            }
        } else if (type == 2) {
            int x = queryHeavy(a, b, c);
            for (vi &v : permutations) {
                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(v);
            }
        } else if (type == 3) {
            int x = queryMed(a, b, c);
            if (x == b) swap(a, b);
            if (x == c) swap(a, c);
            for (vi &v : permutations) {
                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(v);
            }
        } else {
            int d = v[3];
            int x = queryNext(a, b, c, d);
            for (vi &v : permutations) {
                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(v);
            }
        }
        swap(permutations, next);
    }
    for (int i = 0; i < 6; i++) w[i] = permutations[0][i];
    answer(w);
}

//1
//3 4 6 2 1 5

//1
//2 3 1 5 6 4

Compilation message (stderr)

scales.cpp: In function 'bool Solve(vvi&, int)':
scales.cpp:24:30: warning: conversion from 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
   24 |     int n = permutations.size();
      |             ~~~~~~~~~~~~~~~~~^~
scales.cpp: In function 'void init(int)':
scales.cpp:116:15: warning: unused parameter 'T' [-Wunused-parameter]
  116 | void init(int T) {
      |           ~~~~^
scales.cpp: In function 'void orderCoins()':
scales.cpp:171:12: warning: declaration of 'v' shadows a previous local [-Wshadow]
  171 |         vi v = startegy_tree[permutations];
      |            ^
scales.cpp:166:8: note: shadowed declaration is here
  166 |     vi v = {1, 2, 3, 4, 5, 6};
      |        ^
scales.cpp:178:22: warning: declaration of 'v' shadows a previous local [-Wshadow]
  178 |             for (vi &v : permutations) {
      |                      ^
scales.cpp:171:12: note: shadowed declaration is here
  171 |         vi v = startegy_tree[permutations];
      |            ^
scales.cpp:187:22: warning: declaration of 'v' shadows a previous local [-Wshadow]
  187 |             for (vi &v : permutations) {
      |                      ^
scales.cpp:171:12: note: shadowed declaration is here
  171 |         vi v = startegy_tree[permutations];
      |            ^
scales.cpp:198:22: warning: declaration of 'v' shadows a previous local [-Wshadow]
  198 |             for (vi &v : permutations) {
      |                      ^
scales.cpp:171:12: note: shadowed declaration is here
  171 |         vi v = startegy_tree[permutations];
      |            ^
scales.cpp:208:22: warning: declaration of 'v' shadows a previous local [-Wshadow]
  208 |             for (vi &v : permutations) {
      |                      ^
scales.cpp:171:12: note: shadowed declaration is here
  171 |         vi v = startegy_tree[permutations];
      |            ^
#Verdict Execution timeMemoryGrader output
Fetching results...