题目描述:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36627
/*
solution:
IDA*公认经典题,典型的状态空间搜索,但如果套用8数码框架会超时,所以用IDA×算法
note:
注意旋转操作用到数组化不连续为连续,方便了枚举操作(line, center数组)
date:2016/5/10
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
int block[30];
int line[8][7] = {
{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 center[8] = {6, 7, 8, 12, 17, 16, 15, 11};
int rev[8] = {5, 4, 7, 6, 1, 0, 3, 2};
char moves[1000];
bool is_goal() {
for(int i = 1; i < 8; i++)
if(block[center[i]] != block[6])
return false;
return true;
}
void rotation(int dir) {
int tmp = block[line[dir][0]];
for(int i = 1; i < 7; i++)
block[line[dir][i - 1]] = block[line[dir][i]];
block[line[dir][6]] = tmp;
}
int differ(int num) {
int cnt = 0;
for(int i = 0; i < 8; i++)
if(block[center[i]] != num) cnt++;
return cnt;
}
int h() {
return min(min(differ(1), differ(2)), differ(3));
}
bool dfs(int d, int maxd) {
if(d + h() > maxd) return false;
if(is_goal()) {
moves[d] = '\0';
printf("%s\n", moves);
return true;
}
int old_block[30];
for(int i = 0; i < 8; i++) { //向8个方向进行旋转
moves[d] = 'A' + i;
rotation(i);
if(dfs(d + 1, maxd)) return true;
rotation(rev[i]);
}
return false;
}
int main()
{
//freopen("input.txt", "r", stdin);
while(~scanf("%d", &block[0]) && block[0]) {
for(int i = 1; i < 24; i++) scanf("%d", &block[i]);
if(is_goal()) printf("No moves needed\n");
else {
for(int maxd = 1; ;maxd++)
if(dfs(0, maxd))
break;
}
printf("%d\n", block[6]);
}
return 0;
}