您的位置:首页 > 其它

1225 八数码难题

2017-04-22 20:57 197 查看

1225 八数码难题

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 钻石 Diamond

题解
查看运行结果

题目描述 Description

Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.
问题描述

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

输入描述 Input Description

输入初试状态,一行九个数字,空格用0表示

输出描述 Output Description

只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)

样例输入 Sample Input

283104765

样例输出 Sample Output

4

数据范围及提示 Data Size & Hint

详见试题

分类标签 Tags 点此展开

代码有点乱

思路还算清晰

bfs+hash判重

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int MAXN=5;
int xx[5]={-1,+1,0,0};
int yy[5]={0,0,-1,+1};
struct node
{
int mp[MAXN][MAXN];
}a[100001];
int hashfind[3733801];
int step[200];
int h=0,t=1;
int bc[MAXN][MAXN]={{0,0,0,0},{0,1,2,3},{0,8,0,4},{0,7,6,5}};
int hash()
{
int s=0;
int k=1;
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
s=s+a[t].mp[i][j]*k;
k=k*7;
}
}
s=s%3733801;
if(hashfind[s]==0)
{
hashfind[s]=1;
return 1;
}
else
{
return 0;
}
}
int check()
{
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
if(a[t].mp[i][j]!=bc[i][j])
return 0;
}
}
return 1;
}
void move(int x,int y)
{

for(int i=0;i<4;i++)
{
int wx=x+xx[i];
int wy=y+yy[i];
if(wx>=1&&wx<=3&&wy>=1&&wy<=3)
{
for(int j=1;j<=3;j++)
{
for(int k=1;k<=3;k++)
{
a[t].mp[j][k]=a[h].mp[j][k];
}
}
swap(a[t].mp[wx][wy],a[t].mp[x][y]);
step[t]=step[h]+1;
if(check()==1)
{
printf("%d",step[t]);
exit(0);// end
}
if(hash()==1)
t++;
}
}
}
void bfs()
{
while(h<t)
{
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
if(a[h].mp[i][j]==0)
{
move(i,j);
}
}
}
h++;
}
}
int main()
{
char dr[10];
int bgx=0;
int bgy=0;
gets(dr);
int now=0;
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
a[0].mp[i][j]=dr[now]-48;
if(a[0].mp[i][j]==0)
{
bgx=i;
bgy=j;
}
now++;
}
}
bfs();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: