明治ミルクチョコレートパズル(ブラック):回答編
いきなり回答編ですが。
最近研究室の後ろに座ってる人がこれ(http://www.amazon.co.jp/%E3%83%8F%E3%83%8A%E3%83%A4%E3%83%9E-%E6%98%8E%E6%B2%BB%E3%83%9F%E3%83%AB%E3%82%AF%E3%83%81%E3%83%A7%E3%82%B3%E3%83%91%E3%82%BA%E3%83%AB/dp/B000BVN0AA)を持っていて、遊んでいたら元に戻せなくなったのでプログラムを書きました。最初std::vector
#include <iostream> #include <set> using namespace std; typedef unsigned long long ull; char color[10][6]; ull choco[12][8 * 10 * 6]; int choco_size[12]; ull pieces[12] = { 271,527,8642,12676,8327,16833,199,327,28737,31,899,16834 }; inline ull Pos(int i, int j) { return 1LL << (i * 6 + j); } inline ull At(ull n, int i, int j) { return n & Pos(i, j); } ull Rotate90(ull n, int maxr, int maxc) { ull ret = 0; for (int i = 0; i <= maxr; ++i) { for (int j = 0; j <= maxc; ++j) { if (At(n, i, j)) { ret |= Pos(j, maxr - i); } } } return ret; } ull Reverse(ull n, int maxr, int maxc) { ull ret = 0; for (int i = 0; i <= maxr; ++i) { for (int j = 0; j <= maxc; ++j) { if (At(n, i, j)) { ret |= Pos(i, maxc - j); } } } return ret; } int dr[] = {1, 0, -1, 0}; int dc[] = {0, 1, 0, -1}; int Count(ull &b, int r, int c) { b |= Pos(r, c); int ret = 1; for (int i = 0; i < 4; ++i) { int nr = r + dr[i], nc = c + dc[i]; if (0 <= nr && nr < 10 && 0 <= nc && nc < 6 && !At(b, nr, nc)) { ret += Count(b, nr, nc); } } return ret; } void Dfs(int depth, ull board) { static int num = 0; if (depth == 12) { printf("Answer %d:\n", ++num); for (int j = 0; j < 6; ++j) { for (int i = 0; i < 10; ++i) { cout << color[i][j]; } cout << endl; } cout << endl; } else { for (int i = 0; i < choco_size[depth]; ++i) { ull shifted = choco[depth][i]; if (!(board & shifted)) { ull board_shifted = board | shifted; for (int ii = 0; ii < 10; ++ii) { for (int jj = 0; jj < 6; ++jj) { if (At(shifted, ii, jj)) { for (int k = 0; k < 4; ++k) { int iii = ii + dr[k]; int jjj = jj + dc[k]; if (0 <= iii && iii < 10 && 0 <= jjj && jjj < 6 && !At(board_shifted, iii, jjj) && Count(board_shifted, iii, jjj) % 5) { goto NEXT; } } color[ii][jj] = 'A' + depth; } } } Dfs(depth + 1, board | shifted); } NEXT:; } } } int main() { for (int k = 0; k < 12; ++k) { ull piece = pieces[k]; int maxr; int maxc; set<ull> chocok; for (int r = 0; r < 2; ++r) { for (int d = 0; d < 4; ++d) { maxr = 0; maxc = 0; for (int i = 0; i < 10; ++i) { for (int j = 0; j < 6; ++j) { if (At(piece, i, j)) { maxr = max(maxr, i); maxc = max(maxc, j); } } } for (int i = 0; i + maxr < 10; ++i) { for (int j = 0; j + maxc < 6; ++j) { chocok.insert(piece << (i * 6 + j)); } } piece = Rotate90(piece, maxr, maxc); swap(maxr, maxc); } piece = Reverse(piece, maxr, maxc); } for (set<ull>::iterator it = chocok.begin(); it != chocok.end(); ++it) { choco[k][choco_size[k]++] = *it; } } Dfs(0, 0); }
一つの解はこのように表示されます。
Answer 1: ABBHHCIIIJ AABHCCCDIJ AKBHHCDDIJ AKBFFDDLEJ KKGGFLLLEJ KGGGFFLEEE