您的位置:首页 > 其它

IDA*——Luogu1379 八数码难题

2017-03-24 10:31 197 查看
https://www.luogu.org/problem/show?pid=1379

很经典的一道题现在才AC。。。

我的做法和骑士精神那题差不多

IDA*嘛,限制搜索层数然后启发式搜索。。。

一个最优性剪枝:计算每个方块(空格除外)与目标位置的横纵坐标之差的绝对值之和m,如果m不足以在k步之内走到目标位置,剪枝

然后就可以愉快地AC了

其实这题标算好像是双向bfs+康托展开(我不懂啊)

IDA*是水水的(好吧其实这题bfs+hash就能过)

#include<bits/stdc++.h>
using namespace std;
char c[10];
int a[4][4];
bool flag=0;
const int rp[9][2]={{2,2},{1,1},{1,2},{1,3},{2,3},{3,3},{3,2},{3,1},{2,1}};
const int dx[5]={0,1,-1,0,0};
const int dy[5]={0,0,0,1,-1};
inline int A(int a[4][4]){
int sum=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)if(a[i][j])sum+=abs(i-rp[a[i][j]][0])+abs(j-rp[a[i][j]][1]);
return sum;
}
inline void dfs(int p,int a[4][4],int k,int x,int y){
if(flag)return;
int rp=A(a);
if(p==k){
if(rp==0)flag=1;
return;
}
if(p+rp>k)return;
for(int i=1;i<=4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(xx<1||xx>3||yy<1||yy>3)continue;
swap(a[x][y],a[xx][yy]);
dfs(p+1,a,k,xx,yy);
swap(a[x][y],a[xx][yy]);
}
}
int main()
{
int x,y;
scanf("%s",c+1);
for(int i=1,k=1;i<=3;i++,k++){
for(int j=1;j<=3;j++,k++){
a[i][j]=c[k]-'0';
if(a[i][j]==0)x=i,y=j;
}
k--;
}
for(int i=0;;i++){
dfs(0,a,i,x,y);
if(flag){
printf("%d",i);
return 0;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  搜索