您的位置:首页 > 其它

IDA* 解八数码问题: POJ 1077

2015-10-07 21:23 423 查看
刚刚学IDA*,再来写一遍八数码问题。又一次见证了别人家的代码和自己的代码的差距。

别人家的链接:http://www.xuebuyuan.com/1863051.html

h函数自己一开始写的是不在正确位置上的数码的个数,性能低下,T。

更优的一个,也是很多人用的一个就是所有数码与正确位置的曼哈顿距离之和。

然而自己写这个还是T,看了别人家的代码中有个小剪枝,加上后用C++编译还是T,使用G++,1000Ms过。真是压线。

人家的是0Ms。

注:所说的小剪枝是相邻的两步不来回走,在原博客中有代码因为长度过长导致一部分没有显示出来粘贴到Dev上注释会变成乱码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int maxd, mi = 100, beg[10], n[10];
char ans[105];

int h(){
int res = 0;
for(int i = 1; i <= 9; i++){
if(n[i] < 9){
int x = (i-1)/3 + 1;
int y = i % 3; if(!y) y = 3;
int x2 = (n[i]-1)/3 + 1;
int y2 = n[i] % 3; if(!y2) y2 = 3;
res += abs(x-x2)+abs(y-y2);
}
}
mi = min(mi, res);
return res;
}

bool dfs(int ed){
if(!h()){
ans[ed] = '\0';
printf("%s\n", ans);
return 1;
}
if(ed + h() >= maxd) return 0;
int pos = 0;
while(n[pos] < 9) pos++;
if(pos % 3){
swap(n[pos], n[pos+1]);
ans[ed] = 'r';
if(dfs(ed+1)) return 1;
swap(n[pos], n[pos+1]);
}
if(pos <= 6){
swap(n[pos], n[pos+3]);
ans[ed] = 'd';
if(dfs(ed+1)) return 1;
swap(n[pos], n[pos+3]);
}
if(pos > 3){
swap(n[pos], n[pos-3]);
ans[ed] = 'u';
if(dfs(ed+1)) return 1;
swap(n[pos], n[pos-3]);
}
if(pos % 3 != 1){
swap(n[pos], n[pos-1]);
ans[ed] = 'l';
if(dfs(ed+1)) return 1;
swap(n[pos], n[pos-1]);
}
return 0;
}

int main()
{
for(int i = 1; i <= 9; i++){
char s[2]; scanf("%s", s);
if(s[0] != 'x') beg[i] = s[0] - 48;
else beg[i] = 9;
}

int ni = 0;
for(int i = 1; i < 9; i++)
for(int j = i+1; j <= 9; j++){
ni += beg[i] > beg[j] && beg[i] != 9;
}
if(ni&1){
puts("unsolvable");
return 0;
}

for(maxd = h(); ; maxd+=mi){
for(int i = 1; i <= 9; i++) n[i] = beg[i];
if(dfs(0)) return 0;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj