Submission #639926

#TimeUsernameProblemLanguageResultExecution timeMemory
639926piOOE저울 (IOI15_scales)C++17
0 / 100
1099 ms5716 KiB
#include <bits/stdc++.h>
#include "scales.h"

using namespace std;

constexpr int N = 6, M = 720, P[]{1, 3, 9, 27, 81, 243, 729};

map<vector<int>, array<int, 4>> compare;
vector<int> perm[M], inv[M];
int ans[N];

void sort(vector<int> &p, int &i, int &j, int &k) {
    if (p[i] > p[j]) {
        swap(i, j);
    }
    if (p[i] > p[k]) {
        swap(i, k);
    }
    if (p[j] > p[k]) {
        swap(j, k);
    }
}

int heaviest(vector<int> &p, int i, int j, int k) {
    sort(p, i, j, k);
    return k;
}

int median(vector<int> &p, int i, int j, int k) {
    sort(p, i, j, k);
    return j;
}

int lightest(vector<int> &p, int i, int j, int k) {
    sort(p, i, j, k);
    return i;
}

int next(vector<int> &p, int i, int j, int k, int l) {
    sort(p, i, j, k);
    if (p[l] < p[i] || p[l] > p[k]) {
        return i;
    } else if (p[l] < p[j]) {
        return j;
    } else {
        return k;
    }
}

bool solve(vector<int> mask, int remain) {
    if (mask.size() <= 1 || compare.count(mask)) {
        return true;
    } else if (mask.size() > P[remain]) {
        return false;
    }
    for (int i = 0; i < N - 2; ++i) {
        for (int j = i + 1; j < N - 1; ++j) {
            for (int k = j + 1; k < N; ++k) {
                vector<int> one, two, three;
                for (int p: mask) {
                    int x = heaviest(inv[p], i, j, k);
                    (x == i ? one : (x == j ? two : three)).push_back(p);
                }
                if (solve(one, remain - 1) && solve(two, remain - 1) && solve(three, remain - 1)) {
                    compare[mask] = {i, j, k, -1};
                    return true;
                }

                one = two = three = {};
                for (int p: mask) {
                    int x = median(inv[p], i, j, k);
                    (x == i ? one : (x == j ? two : three)).push_back(p);
                }
                if (solve(one, remain - 1) && solve(two, remain - 1) && solve(three, remain - 1)) {
                    compare[mask] = {i, j, k, -2};
                    return true;
                }

                one = two = three = {};
                for (int p: mask) {
                    int x = lightest(inv[p], i, j, k);
                    (x == i ? one : (x == j ? two : three)).push_back(p);
                }
                if (solve(one, remain - 1) && solve(two, remain - 1) && solve(three, remain - 1)) {
                    compare[mask] = {i, j, k, -3};
                    return true;
                }

                for (int l = 0; l < N; ++l) {
                    if (i != l && j != l && k != l) {
                        one = two = three = {};
                        for (int p: mask) {
                            int x = next(inv[p], i, j, k, l);
                            (x == i ? one : (x == j ? two : three)).push_back(p);
                        }
                        if (solve(one, remain - 1) && solve(two, remain - 1) && solve(three, remain - 1)) {
                            compare[mask] = {i, j, k, l};
                            return true;
                        }
                    }
                }
            }
        }
    }
    return false;
}


void init(int T) {
    vector<int> p(N);
    iota(p.begin(), p.end(), 0);
    for (int i = 0; i < M; ++i) {
        inv[i].resize(N);
        for (int k = 0; k < N; ++k) {
            inv[i][p[k]] = k;
        }
        perm[i] = p;
        next_permutation(p.begin(), p.end());
    }
    vector<int> mask(M);
    iota(mask.begin(), mask.end(), 0);
    assert(solve(mask, N));
}

void orderCoins() {
    vector<int> mask(M);
    iota(mask.begin(), mask.end(), 0);

    while (mask.size() > 1) {
        assert(compare.count(mask));
        auto [i, j, k, l] = compare[mask];
        vector<int> one, two, three;
        int y;
        if (l == -1) {
            for (int p: mask) {
                int x = heaviest(inv[p], i, j, k);
                (x == i ? one : x == j ? two : three).push_back(p);
            }
            y = getHeaviest(i + 1, j + 1, k + 1) - 1;
        } else if (l == -2) {
            for (int p: mask) {
                int x = median(inv[p], i, j, k);
                (x == i ? one : x == j ? two : three).push_back(p);
            }
            y = getMedian(i + 1, j + 1, k + 1) - 1;
        } else if (l == -3) {
            for (int p: mask) {
                int x = lightest(inv[p], i, j, k);
                (x == i ? one : x == j ? two : three).push_back(p);
            }
            y = getLightest(i + 1, j + 1, k + 1) - 1;
        } else {
            for (int p: mask) {
                int x = next(inv[p], i, j, k, l);
                (x == i ? one : x == j ? two : three).push_back(p);
            }
            y = getNextLightest(i + 1, j + 1, k + 1, l + 1) - 1;
        }
        mask = (y == i ? one : (y == j ? two : three));
    }

    for (int i = 0; i < N; ++i) {
        ans[i] = perm[mask[0]][i] + 1;
    }

    answer(ans);
}

Compilation message (stderr)

scales.cpp: In function 'bool solve(std::vector<int>, int)':
scales.cpp:53:28: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'const int' [-Wsign-compare]
   53 |     } else if (mask.size() > P[remain]) {
      |                ~~~~~~~~~~~~^~~~~~~~~~~
scales.cpp: In function 'void init(int)':
scales.cpp:109:15: warning: unused parameter 'T' [-Wunused-parameter]
  109 | void init(int T) {
      |           ~~~~^
#Verdict Execution timeMemoryGrader output
Fetching results...