您的位置:首页 > 其它

uva1343

2016-05-15 22:49 363 查看
题目描述: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: