#include // clang-format off using namespace std; void print0(){}; template void print0(H h,T... t){cout<void print(H h,T... t){print0(h);if(sizeof...(T)>0)print0(" ");print(t...);} #define debug1(a) { cerr<<#a<<":"< double(engine() % ANNEAL_RND) / ANNEAL_RND + ANNEAL_EPS); } } // namespace marathon const int N2 = 36; const int N = 6; const int SCORE_BASE = 3; const double END_TIME = 1900; struct six { int val[6]; }; int calc_score(vector> &perm, vector &rolls) { int score = 0; for (int i = 0; i < N; i++) { for (int d = 0; d < N; d++) { int cnt = 0; for (int j = 0; j < N; j++) { int rollid = perm[i][j]; int roll_cnt = rolls[rollid].val[d]; if (!roll_cnt) { cnt = 0; break; } cnt += roll_cnt; } if (!cnt) continue; score += cnt - N + SCORE_BASE; } } for (int j = 0; j < N; j++) { for (int d = 0; d < N; d++) { int cnt = 0; for (int i = 0; i < N; i++) { int rollid = perm[i][j]; int roll_cnt = rolls[rollid].val[d]; if (!roll_cnt) { cnt = 0; break; } cnt += roll_cnt; } if (!cnt) continue; score += cnt - N + SCORE_BASE; } } return score; } int col_score(vector> &perm, vector &rolls, int xj) { int score = 0; { for (int d = 0; d < N; d++) { int cnt = 0; for (int i = 0; i < N; i++) { int rollid = perm[i][xj]; int roll_cnt = rolls[rollid].val[d]; if (!roll_cnt) { cnt = 0; break; } cnt += roll_cnt; } if (!cnt) continue; score += cnt - N + SCORE_BASE; } } return score; } int row_score(vector> &perm, vector &rolls, int xi) { int score = 0; { for (int d = 0; d < N; d++) { int cnt = 0; for (int j = 0; j < N; j++) { int rollid = perm[xi][j]; int roll_cnt = rolls[rollid].val[d]; if (!roll_cnt) { cnt = 0; break; } cnt += roll_cnt; } if (!cnt) continue; score += cnt - N + SCORE_BASE; } } return score; } void anneal(vector rolls) { vector> perm(N, vector(N)); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { perm[i][j] = i * N + j; } } int old_score = calc_score(perm, rolls); vector> best_perm = perm; int best_score = old_score; double begin_time = marathon::now(); double end_time = END_TIME; double begin_temp = 2.0; double end_temp = begin_temp * 0.1; int anneal_iter = 0; int anneal_accept = 0; while (marathon::now() < END_TIME) { anneal_iter++; int x = 0; int y = 0; while (x == y) { x = marathon::engine() % N2; y = marathon::engine() % N2; } int xi = x / N; int xj = x % N; int yi = y / N; int yj = y % N; int new_score = old_score; if (xi != yi) { new_score -= row_score(perm, rolls, xi); new_score -= row_score(perm, rolls, yi); } if (xj != yj) { new_score -= col_score(perm, rolls, xj); new_score -= col_score(perm, rolls, yj); } swap(perm[xi][xj], perm[yi][yj]); if (xi != yi) { new_score += row_score(perm, rolls, xi); new_score += row_score(perm, rolls, yi); } if (xj != yj) { new_score += col_score(perm, rolls, xj); new_score += col_score(perm, rolls, yj); } if (best_score < new_score) { best_perm = perm; best_score = new_score; } if (marathon::anneal_accept(new_score, old_score, marathon::now(), begin_time, end_time, begin_temp, end_temp)) { anneal_accept++; old_score = new_score; } else { swap(perm[xi][xj], perm[yi][yj]); } } debug3(anneal_iter, anneal_accept, best_score); vector> revperm(N2); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { revperm[best_perm[i][j]] = {i, j}; } } for (int i = 0; i < N2; i++) { print(revperm[i].first + 1, revperm[i].second + 1); } } int main() { marathon::marathon_init(); vector rolls(N2); for (int i = 0; i < N2; i++) { six s; for (int k = 0; k < N; k++) { s.val[k] = 0; } for (int j = 0; j < N; j++) { int d; cin >> d; d--; s.val[d]++; } rolls[i] = s; } anneal(rolls); return 0; }