제출 #424563

#제출 시각아이디문제언어결과실행 시간메모리
424563KoDScales (IOI15_scales)C++17
0 / 100
20 ms1356 KiB
#include <bits/stdc++.h>
#include "scales.h"

template <class T> using Vec = std::vector<T>;

std::array<std::array<int, 6>, 720> perm;
std::array<std::array<int, 4>, 120> query;
std::array<std::array<int, 120>, 720> rsp;

std::map<Vec<int>, int> memo;
int find_next(const Vec<int>& cand) {
    const auto itr = memo.find(cand);
    if (itr != memo.end()) {
        return itr -> second;
    }
    const int sz = (int) cand.size();
    if (sz == 1)  { 
        return memo[cand] = -2;
    }
    int nsz = 1;
    while (nsz * 3 < sz) {
        nsz *= 3;
    }
    for (int i = 0; i < 120; ++i) {
        std::map<int, Vec<int>> next;
        for (const int p : cand) {
            next[rsp[i][p]].push_back(p);
        }
        bool ok = true;
        for (const auto& p: next) {
            if ((int) p.second.size() > nsz or find_next(p.second) == -1) {
                ok = false;
                break;
            }
        }
        if (ok) {
            return memo[cand] = i;
        }
    }
    return memo[cand] = -1;
}

void init(int) {
    std::array<int, 6> ord;
    std::iota(ord.begin(), ord.end(), 1);
    for (int i = 0; i < 720; ++i) {
        perm[i] = ord;
        std::next_permutation(ord.begin(), ord.end());
    }
    int idx = 0;
    for (int i = 0; i < 6; ++i) {
        for (int j = i + 1; j < 6; ++j) {
            for (int k = j + 1; k < 6; ++k) {
                for (int l = 0; l < 6; ++l) {
                    query[idx++] = {i, j, k, l};
                }
            }
        }
    }
    for (int i = 0; i < 120; ++i) {
        auto ord = query[i];
        for (int p = 0; p < 720; ++p) {
            std::sort(ord.begin(), ord.begin() + 3, [&](const int x, const int y) {
                return perm[p][x] < perm[p][y];
            });
            bool done = false;
            for (int k = 0; k < 3; ++k) {
                if (query[i][k] == query[i][3]) {
                    rsp[i][p] = ord[k];
                    done = true;
                }
            }
            if (!done) {
                int idx = 0;
                while (perm[p][ord[idx]] < perm[p][ord[3]]) {
                    idx += 1;
                }
                rsp[i][p] = (idx == 3 ? ord[0] : ord[idx]);
            }
        }
    }
}

void orderCoins() {
    Vec<int> cand(720);
    std::iota(cand.begin(), cand.end(), 0);
    while (cand.size() > 1) {
        const auto i = find_next(cand);
        const auto [a, b, c, d] = query[i];
        Vec<int> next;
        const auto e = [&] {
            if (a == d) return getLightest(a + 1, b + 1, c + 1) - 1;
            if (b == d) return getMedian(a + 1, b + 1, c + 1) - 1;
            if (c == d) return getHeaviest(a + 1, b + 1, c + 1) - 1;
            return getNextLightest(a + 1, b + 1, c + 1, d + 1) - 1;
        }();
        for (const auto p : cand) {
            if (rsp[i][p] == e) {
                next.push_back(p);
            }
        }
        cand = std::move(next);
    }
    const int p = cand[0];
    int W[6];
    std::iota(W, W + 6, 0);
    std::sort(W, W + 6, [&](const int x, const int y) {
        return perm[p][x] < perm[p][y];
    });
    for (auto& x : W) {
        x += 1;
    }
    answer(W);
}

컴파일 시 표준 에러 (stderr) 메시지

scales.cpp: In function 'void init(int)':
scales.cpp:61:14: warning: declaration of 'ord' shadows a previous local [-Wshadow]
   61 |         auto ord = query[i];
      |              ^~~
scales.cpp:44:24: note: shadowed declaration is here
   44 |     std::array<int, 6> ord;
      |                        ^~~
scales.cpp:74:21: warning: declaration of 'idx' shadows a previous local [-Wshadow]
   74 |                 int idx = 0;
      |                     ^~~
scales.cpp:50:9: note: shadowed declaration is here
   50 |     int idx = 0;
      |         ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...