Submission #551033

#TimeUsernameProblemLanguageResultExecution timeMemory
551033elazarkorenScales (IOI15_scales)C++17
0 / 100
1094 ms7108 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, pair<int, 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)) {
                    if (!x) {
                        cout << "";
                    }
                    startegy_tree[permutations] = {1, {a, b, c}};
                    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)) {
                    if (!x) {
                        cout << "";
                    }
                    startegy_tree[permutations] = {2, {a, b, c}};
                    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)) {
                    if (!x) {
                        cout << "";
                    }
                    startegy_tree[permutations] = {3, {a, b, c}};
                    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)) {
                        if (!x) {
                            cout << "";
                        }
                        startegy_tree[permutations] = {4, {a, b, c, d}};
                        return true;
                    }
                }
            }
        }
    }
    if (!x) {
        cout << "";
    }
    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;
    vi v = {1, 2, 3, 4, 5, 6};
    do {
        permutations.push_back(v);
    } while (next_permutation(all(v)));
    while (permutations.size() > 1) {
        auto [type, v] = startegy_tree[permutations];
        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:131:15: warning: unused parameter 'T' [-Wunused-parameter]
  131 | void init(int T) {
      |           ~~~~^
scales.cpp: In function 'void orderCoins()':
scales.cpp:185:21: warning: declaration of 'v' shadows a previous local [-Wshadow]
  185 |         auto [type, v] = startegy_tree[permutations];
      |                     ^
scales.cpp:180:8: note: shadowed declaration is here
  180 |     vi v = {1, 2, 3, 4, 5, 6};
      |        ^
scales.cpp:191:22: warning: declaration of 'v' shadows a previous local [-Wshadow]
  191 |             for (vi &v : permutations) {
      |                      ^
scales.cpp:185:21: note: shadowed declaration is here
  185 |         auto [type, v] = startegy_tree[permutations];
      |                     ^
scales.cpp:200:22: warning: declaration of 'v' shadows a previous local [-Wshadow]
  200 |             for (vi &v : permutations) {
      |                      ^
scales.cpp:185:21: note: shadowed declaration is here
  185 |         auto [type, v] = startegy_tree[permutations];
      |                     ^
scales.cpp:211:22: warning: declaration of 'v' shadows a previous local [-Wshadow]
  211 |             for (vi &v : permutations) {
      |                      ^
scales.cpp:185:21: note: shadowed declaration is here
  185 |         auto [type, v] = startegy_tree[permutations];
      |                     ^
scales.cpp:221:22: warning: declaration of 'v' shadows a previous local [-Wshadow]
  221 |             for (vi &v : permutations) {
      |                      ^
scales.cpp:185:21: note: shadowed declaration is here
  185 |         auto [type, v] = startegy_tree[permutations];
      |                     ^
#Verdict Execution timeMemoryGrader output
Fetching results...