제출 #797404

#제출 시각아이디문제언어결과실행 시간메모리
797404thimote75저울 (IOI15_scales)C++14
100 / 100
101 ms516 KiB
#include "scales.h" #include <bits/stdc++.h> using namespace std; using idata = vector<int>; using igrid = vector<idata>; const int STATE_SIZE = 6; igrid all_states; struct Status { idata states_possible; void show () { for (int pos : states_possible) { cout << "[ "; for (int u : all_states[pos]) cout << u << " "; cout << "] "; } cout << endl; } }; struct Move { bool is_valid = false; bool is_answer = false; int answer_id = -1; int type; int A, B, C, D; Move* resA = nullptr; Move* resB = nullptr; Move* resC = nullptr; Move (bool valid) { is_valid = valid; } Move (bool valid, bool answer) { is_valid = valid; is_answer = answer; } Move (int result) { is_valid = true; is_answer = true; answer_id = result; } void show_spaces (int depth) { for (int u = 0; u < depth; u ++) cout << " "; } void show (int depth = 0) { if (is_answer) { if (answer_id == -1) { cout << endl; return ; } show_spaces(depth); for (int u : all_states[answer_id]) cout << u << " "; cout << endl; return ; } show_spaces(depth); cout << type << ": " << A << " " << B << " " << C; if (type == 4) cout << " " << D; cout << endl; if (resA != nullptr) resA->show(depth + 1); if (resB != nullptr) resB->show(depth + 1); if (resC != nullptr) resC->show(depth + 1); } Move* traverse () { if (is_answer) return this; int result; if (type == 0) result = getHeaviest(A, B, C); if (type == 1) result = getMedian (A, B, C); if (type == 2) result = getLightest(A, B, C); if (type == 4) result = getNextLightest(A, B, C, D); if (result == A) return resA; if (result == B) return resB; if (result == C) return resC; return this; } }; Status filter_gamma (Status &state, int a, int b, int c, int result, int gamma) { Status answer; for (int answer_id : state.states_possible) { int res = 0; for (int u : all_states[answer_id]) { if (u == a || u == b || u == c) res ++; if (u == result) break ; } if (res != gamma) continue ; answer.states_possible.push_back(answer_id); } return answer; } Status filter (Status &state, int type, int a, int b, int c, int result) { if (type == 0) return filter_gamma(state, a, b, c, result, 3); if (type == 1) return filter_gamma(state, a, b, c, result, 2); if (type == 2) return filter_gamma(state, a, b, c, result, 1); return state; } Status filter4 (Status &state, int a, int b, int c, int d, int result) { Status answer; for (int answer_id : state.states_possible) { int first = -1; int res = 0; for (int u : all_states[answer_id]) { if (a == u || b == u || c == u) { res ++; if (first == -1) first = u; if (res == 3) break ; } if (u == d) { first = -1; } } if (first != result) continue ; answer.states_possible.push_back(answer_id); } return answer; } Move* traverse (Status &state, int rem) { if (state.states_possible.size() == 0) return new Move(true, true); if (state.states_possible.size() == 1) return new Move(state.states_possible[0]); int nextRem = rem / 3; for (int type = 0; type < 3; type ++) { for (int a = 1; a <= STATE_SIZE; a ++) { for (int b = 1; b <= STATE_SIZE; b ++) { if (a == b) continue ; for (int c = 1; c <= STATE_SIZE; c ++) { if (a == c || b == c) continue ; Status sA = filter(state, type, a, b, c, a); if (sA.states_possible.size() > nextRem) continue ; Status sB = filter(state, type, a, b, c, b); if (sB.states_possible.size() > nextRem) continue ; Status sC = filter(state, type, a, b, c, c); if (sC.states_possible.size() > nextRem) continue ; Move* mA = traverse(sA, nextRem); if (!mA->is_valid) continue ; Move* mB = traverse(sB, nextRem); if (!mB->is_valid) continue ; Move* mC = traverse(sC, nextRem); if (!mC->is_valid) continue ; //cout << rem << ": " << type << " " << a << " " << b << " " << c << "\n"; Move* result = new Move(true); result->A = a; result->B = b; result->C = c; result->resA = mA; result->resB = mB; result->resC = mC; result->type = type; return result; } } } } for (int a = 1; a <= STATE_SIZE; a ++) { for (int b = 1; b <= STATE_SIZE; b ++) { if (a == b) continue ; for (int c = 1; c <= STATE_SIZE; c ++) { if (a == c || b == c) continue ; for (int d = 1; d <= STATE_SIZE; d ++) { if (a == d || b == d || c == d) continue ; Status sA = filter4(state, a, b, c, d, a); if (sA.states_possible.size() > nextRem) continue ; Status sB = filter4(state, a, b, c, d, b); if (sB.states_possible.size() > nextRem) continue ; Status sC = filter4(state, a, b, c, d, c); if (sC.states_possible.size() > nextRem) continue ; Move* mA = traverse(sA, nextRem); if (!mA->is_valid) continue ; Move* mB = traverse(sB, nextRem); if (!mB->is_valid) continue ; Move* mC = traverse(sC, nextRem); if (!mC->is_valid) continue ; Move* result = new Move(true); result->type = 4; result->A = a; result->B = b; result->C = c; result->D = d; result->resA = mA; result->resB = mB; result->resC = mC; //cout << rem << ": " << 4 << " " << a << " " << b << " " << c << "\n"; return result; } } } } return new Move(false); } void init_states (vector<int> &values) { if (values.size() == STATE_SIZE) { all_states.push_back(values); return ; } for (int i = 1; i <= STATE_SIZE; i ++) { bool unique = true; for (int u : values) if (i == u) unique = false; if (!unique) continue ; values.push_back(i); init_states(values); values.pop_back(); } } Move* answerMove; void init(int T) { vector<int> state; init_states(state); Status initial_state; for (int i = 0; i < all_states.size(); i ++) initial_state.states_possible.push_back(i); answerMove = traverse(initial_state, 729); } void orderCoins() { Move* localMove = answerMove; for (int i = 0; i < 6; i ++) localMove = localMove->traverse(); int ans[STATE_SIZE]; for (int i = 0; i < STATE_SIZE; i ++) ans[i] = all_states[localMove->answer_id][i]; answer(ans); }

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

scales.cpp: In member function 'void Move::show(int)':
scales.cpp:61:13: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
   61 |             for (int u : all_states[answer_id]) cout << u << " "; cout << endl;
      |             ^~~
scales.cpp:61:67: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
   61 |             for (int u : all_states[answer_id]) cout << u << " "; cout << endl;
      |                                                                   ^~~~
scales.cpp: In function 'Move* traverse(Status&, int)':
scales.cpp:151:51: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  151 |                     if (sA.states_possible.size() > nextRem) continue ;
      |                         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
scales.cpp:153:51: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  153 |                     if (sB.states_possible.size() > nextRem) continue ;
      |                         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
scales.cpp:155:51: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  155 |                     if (sC.states_possible.size() > nextRem) continue ;
      |                         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
scales.cpp:189:51: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  189 |                     if (sA.states_possible.size() > nextRem) continue ;
      |                         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
scales.cpp:191:51: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  191 |                     if (sB.states_possible.size() > nextRem) continue ;
      |                         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
scales.cpp:193:51: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  193 |                     if (sC.states_possible.size() > nextRem) continue ;
      |                         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
scales.cpp: In function 'void init(int)':
scales.cpp:247:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  247 |     for (int i = 0; i < all_states.size(); i ++) initial_state.states_possible.push_back(i);
      |                     ~~^~~~~~~~~~~~~~~~~~~
scales.cpp:243:15: warning: unused parameter 'T' [-Wunused-parameter]
  243 | void init(int T) {
      |           ~~~~^
scales.cpp: In function 'void orderCoins()':
scales.cpp:84:9: warning: 'result' may be used uninitialized in this function [-Wmaybe-uninitialized]
   84 |         if (result == B) return resB;
      |         ^~
scales.cpp:77:13: note: 'result' was declared here
   77 |         int result;
      |             ^~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...