제출 #590922

#제출 시각아이디문제언어결과실행 시간메모리
590922lorenzoferrari저울 (IOI15_scales)C++17
0 / 100
1098 ms340 KiB
#include "scales.h" #include <bits/stdc++.h> using namespace std; #define sz size using perm = array<int8_t, 6>; struct op { int8_t type; array<int8_t, 4> args; op() : type(-1) {} op(int8_t w, array<int, 4> a) : type(w) { args[0] = a[0]; args[1] = a[1]; args[2] = a[2]; args[3] = a[3]; } int8_t get_type() const { return type; } int8_t operator[](const int i) const { return args[i]; } }; ostream& operator<<(ostream& os, const op& o) { os << "(" << int(o.type) << ", {" << int(o[0]) << "," << int(o[1]) << "," << int(o[2]); if (o.type == 3) os << "," << int(o[3]); os << "})"; return os; } struct query { op o; int8_t ans; query() : ans(-1) {} query(const op& o, const int8_t a) : o(o), ans(a) {} int8_t type() const { return o.get_type(); } int8_t operator[](const int i) const { return o[i]; } }; bool works(const perm& p, const query& q) { if (q.type() != 3) { int cnt = 0; for (int i = 0; i < 3; ++i) { cnt += (p[q[i]] > p[q[q.ans]]); } return cnt == q.type(); } else { int cnt = 0; for (int i = 0; i < 3; ++i) cnt += (p[q[i]] > p[q[3]]); int tans = -1; if (cnt == 0) { if (p[q[0]] < p[q[tans]] || tans == -1) tans = 0; if (p[q[1]] < p[q[tans]] || tans == -1) tans = 1; if (p[q[2]] < p[q[tans]] || tans == -1) tans = 2; } else { if (p[q[0]] > p[q[3]] && (tans == -1 || p[q[0]] < p[q[tans]])) tans = 0; if (p[q[1]] > p[q[3]] && (tans == -1 || p[q[1]] < p[q[tans]])) tans = 1; if (p[q[2]] > p[q[3]] && (tans == -1 || p[q[2]] < p[q[tans]])) tans = 2; } return q.ans == tans; } } array<vector<perm>, 3> simulate(const vector<perm>& cur, const op& o) { array<vector<perm>, 3> ans; for (const perm& p : cur) { for (int i = 0; i < 3; ++i) { if (works(p, query(o, i))) ans[i].push_back(p); } } return ans; } void answer(int w[]); int getHeaviest(int A, int B, int C); // type 0 int getMedian(int A, int B, int C); // type 1 int getLightest(int A, int B, int C); // type 2 int getNextLightest(int A, int B, int C, int D); // type 3 void actually_ask(vector<perm>& cur, const op& o) { // cerr << "asked: " << o << "\n"; auto s = simulate(cur, o); int ans = -1; switch (o.type) { case 0: ans = getHeaviest(o[0]+1, o[1]+1, o[2]+1); break; case 1: ans = getMedian(o[0]+1, o[1]+1, o[2]+1); break; case 2: ans = getLightest(o[0]+1, o[1]+1, o[2]+1); break; case 3: ans = getNextLightest(o[0]+1, o[1]+1, o[2]+1, o[3]+1); break; } for (int i = 0; i < 4; ++i) { if (ans-1 == o[i]) { // cerr << ans << "\n"; cur = s[i]; break; } } } int T; vector<perm> perms; void init(int T) { ::T = T; perms.reserve(720); perm p{0,1,2,3,4,5}; do { perms.push_back(p); } while (next_permutation(p.begin(), p.end())); } struct record { op operation; int worst_case; record() {} record(const op o, const int wc) : operation(o), worst_case(wc) {} }; record run_simulation(const vector<perm>& cur, int depth) { record ans; ans.worst_case = 1e9; ans.operation = op(-1, {-1,-1,-1,-1}); if (depth == 0 || int(cur.size()) <= 1) { ans.worst_case = cur.size(); } else { for (int a = 0; a < 6; ++a) for (int b = a+1; b < 6; ++b) for (int c = b+1; c < 6; ++c) { array<op, 3> operators; operators[0] = op(0, {a, b, c}); operators[1] = op(1, {a, b, c}); operators[2] = op(2, {a, b, c}); for (int i = 0; i < 3; ++i) { auto s = simulate(cur, operators[i]); int cur_worst_case = 0; for (int j = 0; j < 3; ++j) { cur_worst_case = max(cur_worst_case, run_simulation(s[j], depth - 1).worst_case); } if (cur_worst_case < ans.worst_case) { ans.worst_case = cur_worst_case; ans.operation = operators[i]; } } for (int d = 0; d < 6; ++d) { if (d == a || d == b || d == c) continue; op o3(3, {a, b, c, d}); auto s = simulate(cur, o3); int cur_worst_case = 0; for (int j = 0; j < 3; ++j) { cur_worst_case = max(cur_worst_case, run_simulation(s[j], depth - 1).worst_case); } if (cur_worst_case < ans.worst_case) { ans.worst_case = cur_worst_case; ans.operation = o3; } } } } return ans; } void orderCoins() { vector<perm> cur = perms; actually_ask(cur, op(0, {0, 1, 2})); actually_ask(cur, op(0, {3, 4, 5})); while (cur.size() != 1) { record r; int steps = 0; while ((r = run_simulation(cur, steps)).worst_case > 1 && steps < 2) { r = run_simulation(cur, steps); // cerr << " > r.op = " << r.operation << "\n"; // cerr << " > steps = " << steps << "\n"; if (r.worst_case > 1 ) ++steps; } // cerr << "cur.size(): " << cur.size() << "\n"; // cerr << "worst_case: " << r.worst_case << "\n"; actually_ask(cur, r.operation); } int w[6]; for (int i = 0; i < 6; ++i) { w[cur[0][i]] = i+1; } answer(w); }

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

scales.cpp: In constructor 'op::op(int8_t, std::array<int, 4>)':
scales.cpp:14:18: warning: conversion from 'std::array<int, 4>::value_type' {aka 'int'} to 'std::array<signed char, 4>::value_type' {aka 'signed char'} may change value [-Wconversion]
   14 |     args[0] = a[0];
      |                  ^
scales.cpp:15:18: warning: conversion from 'std::array<int, 4>::value_type' {aka 'int'} to 'std::array<signed char, 4>::value_type' {aka 'signed char'} may change value [-Wconversion]
   15 |     args[1] = a[1];
      |                  ^
scales.cpp:16:18: warning: conversion from 'std::array<int, 4>::value_type' {aka 'int'} to 'std::array<signed char, 4>::value_type' {aka 'signed char'} may change value [-Wconversion]
   16 |     args[2] = a[2];
      |                  ^
scales.cpp:17:18: warning: conversion from 'std::array<int, 4>::value_type' {aka 'int'} to 'std::array<signed char, 4>::value_type' {aka 'signed char'} may change value [-Wconversion]
   17 |     args[3] = a[3];
      |                  ^
scales.cpp: In constructor 'query::query(const op&, int8_t)':
scales.cpp:33:19: warning: declaration of 'o' shadows a member of 'query' [-Wshadow]
   33 |   query(const op& o, const int8_t a) : o(o), ans(a) {}
      |         ~~~~~~~~~~^
scales.cpp:30:6: note: shadowed declaration is here
   30 |   op o;
      |      ^
scales.cpp: In constructor 'query::query(const op&, int8_t)':
scales.cpp:33:19: warning: declaration of 'o' shadows a member of 'query' [-Wshadow]
   33 |   query(const op& o, const int8_t a) : o(o), ans(a) {}
      |         ~~~~~~~~~~^
scales.cpp:30:6: note: shadowed declaration is here
   30 |   op o;
      |      ^
scales.cpp: In constructor 'query::query(const op&, int8_t)':
scales.cpp:33:19: warning: declaration of 'o' shadows a member of 'query' [-Wshadow]
   33 |   query(const op& o, const int8_t a) : o(o), ans(a) {}
      |         ~~~~~~~~~~^
scales.cpp:30:6: note: shadowed declaration is here
   30 |   op o;
      |      ^
scales.cpp: In function 'std::array<std::vector<std::array<signed char, 6> >, 3> simulate(const std::vector<std::array<signed char, 6> >&, const op&)':
scales.cpp:66:29: warning: conversion from 'int' to 'int8_t' {aka 'signed char'} may change value [-Wconversion]
   66 |       if (works(p, query(o, i))) ans[i].push_back(p);
      |                             ^
scales.cpp: In function 'void init(int)':
scales.cpp:108:15: warning: declaration of 'T' shadows a global declaration [-Wshadow]
  108 | void init(int T) {
      |           ~~~~^
scales.cpp:105:5: note: shadowed declaration is here
  105 | int T;
      |     ^
scales.cpp: In function 'record run_simulation(const std::vector<std::array<signed char, 6> >&, int)':
scales.cpp:129:30: warning: conversion from 'std::vector<std::array<signed char, 6> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
  129 |     ans.worst_case = cur.size();
      |                      ~~~~~~~~^~
#Verdict Execution timeMemoryGrader output
Fetching results...