Submission #237987

#TimeUsernameProblemLanguageResultExecution timeMemory
237987rama_pangScales (IOI15_scales)C++14
100 / 100
727 ms508 KiB
#include "scales.h" #include <bits/stdc++.h> using namespace std; const int N = 720; using state = bitset<N>; vector<vector<int>> combinations; // take 4 coins' ids vector<vector<int>> permutations; // weights of each coin function<int(int, int, int, int, int)> Lightest = [&](int P, int A, int B, int C, int D) { if (P == -1) { return getLightest(A + 1, B + 1, C + 1) - 1; } else { const vector<int> &cur = permutations[P]; vector<array<int, 2>> weights = {{cur[A], A}, {cur[B], B}, {cur[C], C}}; sort(begin(weights), end(weights)); return weights[0][1]; } }; function<int(int, int, int, int, int)> Median = [&](int P, int A, int B, int C, int D) { if (P == -1) { return getMedian(A + 1, B + 1, C + 1) - 1; } else { const vector<int> &cur = permutations[P]; vector<array<int, 2>> weights = {{cur[A], A}, {cur[B], B}, {cur[C], C}}; sort(begin(weights), end(weights)); return weights[1][1]; } }; function<int(int, int, int, int, int)> Heaviest = [&](int P, int A, int B, int C, int D) { if (P == -1) { return getHeaviest(A + 1, B + 1, C + 1) - 1; } else { const vector<int> &cur = permutations[P]; vector<array<int, 2>> weights = {{cur[A], A}, {cur[B], B}, {cur[C], C}}; sort(begin(weights), end(weights)); return weights[2][1]; } }; function<int(int, int, int, int, int)> NextLightest = [&](int P, int A, int B, int C, int D) { if (P == -1) { return getNextLightest(A + 1, B + 1, C + 1, D + 1) - 1; } else { const vector<int> &cur = permutations[P]; vector<array<int, 2>> weights = {{cur[A], A}, {cur[B], B}, {cur[C], C}}; sort(begin(weights), end(weights)); if (cur[D] < weights[0][0]) return weights[0][1]; if (cur[D] < weights[1][0]) return weights[1][1]; if (cur[D] < weights[2][0]) return weights[2][1]; return weights[0][1]; } }; void init(int T) { for (int mask = 0; mask < (1 << 6); mask++) { if (__builtin_popcount(mask) == 4) { vector<int> active; for (int i = 0; i < 6; i++) { if (mask & (1 << i)) { active.emplace_back(i); } } do { combinations.emplace_back(active); } while (next_permutation(begin(active), end(active))); } } vector<int> p = {0, 1, 2, 3, 4, 5}; do { permutations.emplace_back(p); } while (next_permutation(begin(p), end(p))); } bool Solve(const state &candidates, int depth); bool Try(const state &perms, const function<int(int, int, int, int, int)> &f, int depth) { for (auto &comb : combinations) { int mx = 0; for (int ans = 0; ans < 4; ans++) { int can = 0; for (int p = 0; p < N; p++) if (perms[p]) { if (f(p, comb[0], comb[1], comb[2], comb[3]) == comb[ans]) { can++; } } mx = max(mx, can); } int cnt = perms.count(); bool transition = false; if (243 < cnt && cnt <= 720) transition |= mx <= 240; if (81 < cnt && cnt <= 243) transition |= mx <= 81; if (27 < cnt && cnt <= 81) transition |= mx <= 27; if (9 < cnt && cnt <= 27) transition |= mx <= 9; if (3 < cnt && cnt <= 9) transition |= mx <= 3; if (0 < cnt && cnt <= 3) transition |= mx <= 1; if (transition) { int ans = f(-1, comb[0], comb[1], comb[2], comb[3]); state can = 0; for (int p = 0; p < N; p++) if (perms[p]) { if (f(p, comb[0], comb[1], comb[2], comb[3]) == ans) { can[p] = 1; } } return Solve(can, depth + 1); } } return false; } bool Solve(const state &candidates, int depth = 0) { if (candidates.count() == 1) { int pid = candidates._Find_first(); vector<int> order(6); for (int i = 0; i < 6; i++) { order[permutations[pid][i]] = i + 1; } answer(order.data()); return true; } else if (depth % 4 == 0) { return Try(candidates, Lightest, depth) || Try(candidates, Median, depth) || Try(candidates, Heaviest, depth) || Try(candidates, NextLightest, depth); } else if (depth % 4 == 1) { return Try(candidates, Median, depth) || Try(candidates, Heaviest, depth) || Try(candidates, NextLightest, depth) || Try(candidates, Lightest, depth); } else if (depth % 4 == 2) { return Try(candidates, Heaviest, depth) || Try(candidates, NextLightest, depth) || Try(candidates, Lightest, depth) || Try(candidates, Median, depth); } else if (depth % 4 == 3) { return Try(candidates, NextLightest, depth) || Try(candidates, Lightest, depth) || Try(candidates, Median, depth) || Try(candidates, Heaviest, depth); } } void orderCoins() { state candidates; for (int i = 0; i < N; i++) candidates[i] = 1; assert(Solve(candidates)); }

Compilation message (stderr)

scales.cpp: In lambda function:
scales.cpp:11:87: warning: unused parameter 'D' [-Wunused-parameter]
 function<int(int, int, int, int, int)> Lightest = [&](int P, int A, int B, int C, int D) {
                                                                                       ^
scales.cpp: In lambda function:
scales.cpp:22:85: warning: unused parameter 'D' [-Wunused-parameter]
 function<int(int, int, int, int, int)> Median = [&](int P, int A, int B, int C, int D) {
                                                                                     ^
scales.cpp: In lambda function:
scales.cpp:33:87: warning: unused parameter 'D' [-Wunused-parameter]
 function<int(int, int, int, int, int)> Heaviest = [&](int P, int A, int B, int C, int D) {
                                                                                       ^
scales.cpp: In function 'void init(int)':
scales.cpp:58:15: warning: unused parameter 'T' [-Wunused-parameter]
 void init(int T) {
               ^
scales.cpp: In function 'bool Try(const state&, const std::function<int(int, int, int, int, int)>&, int)':
scales.cpp:94:26: warning: conversion to 'int' from 'std::size_t {aka long unsigned int}' may alter its value [-Wconversion]
     int cnt = perms.count();
               ~~~~~~~~~~~^~
scales.cpp: In function 'bool Solve(const state&, int)':
scales.cpp:118:37: warning: conversion to 'int' from 'std::size_t {aka long unsigned int}' may alter its value [-Wconversion]
     int pid = candidates._Find_first();
               ~~~~~~~~~~~~~~~~~~~~~~^~
scales.cpp:138:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
#Verdict Execution timeMemoryGrader output
Fetching results...