# The Rotation Game

## 题目描述

The rotation game uses a # shaped board, which can hold $24$ pieces of square blocks (see Fig.1). The blocks are marked with symbols 1, 2 and 3, with exactly $8$ pieces of each kind. Initially, the blocks are placed on the board randomly. Your task is to move the blocks so that the eight blocks placed in the center square have the same symbol marked. There is only one type of valid move, which is to rotate one of the four lines, each consisting of seven blocks. That is, six blocks in the line are moved towards the head by one block and the head block is moved to the end of the line. The eight possible moves are marked with capital letters A to H. Figure 1 illustrates two consecutive moves, move A and move C from some initial configuration.

## 代码

#include <cstdio>

int max(int a, int b) {
return a > b ? a : b;
}

static const int TAR[] = { 6, 7, 8, 11, 12, 15, 16, 17 };
static const int OPER[] = {
{ 0,   2,   6,   11,  15,  20,  22 },
{ 1,   3,   8,   12,  17,  21,  23 },
{ 10,  9,   8,   7,   6,   5,   4 },
{ 19,  18,  17,  16,  15,  14,  13 },
{ 23,  21,  17,  12,  8,   3,   1 },
{ 22,  20,  15,  11,  6,   2,   0 },
{ 13,  14,  15,  16,  17,  18,  19 },
{ 4,   5,   6,   7,   8,   9,   10 }
};
int limit, cnt, a, o;

int get_h() {
cnt = cnt = cnt = 0;
for (int i = 0; i < 8; ++ i) ++ cnt[a[TAR[i]] - 1];
return 8 - max(cnt, max(cnt, cnt));
}

bool is_inv(int a, int b) {
if (a > b) a ^= b ^= a ^= b;
return (a == 0 && b == 5) || (a == 1 && b == 4) || (a == 2 && b == 7) || (a == 3 && b == 6);
}

bool dfs(int t, int last) {
if (t == limit) return ! get_h();
if (t + get_h() > limit) return false;
for (int i = 0; i < 8; ++ i)
if (! ~ last || ! is_inv(last, i)) {
int tmp = a[OPER[i]];
for (int j = 0; j < 6; ++ j) a[OPER[i][j]] = a[OPER[i][j + 1]];
a[OPER[i]] = tmp, o[t] = i;
if (dfs(t + 1, i)) return true;
tmp = a[OPER[i]];
for (int j = 6; j; -- j) a[OPER[i][j]] = a[OPER[i][j - 1]];
a[OPER[i]] = tmp;
}
return false;
}

int main() {
while (scanf("%d", &a), a) {
for (int i = 1; i < 24; ++ i) scanf("%d", &a[i]);
for (limit = 0; ; ++ limit)
if (dfs(0, -1)) {
if (limit) for (int i = 0; i < limit; ++ i) printf("%c", 'A' + o[i]);
else printf("No moves needed");
printf("\n%d\n", a); break;
}
}
return 0;
} 418 I'm a teapot