您的位置:首页 > 其它

八数码难题

2015-08-17 20:08 330 查看

题目描述 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

详见试题

解题思路

由题意得(讨厌这句话),这是一道搜索题,由于是找最少移动次数,所以应该是用广度优先搜索,为了节约时间,采用双向宽度优先搜索。当然,这是我第一次写双向宽搜,

应该有优化,但我并不知道怎么写,话说还有一个叫A*的算法……不造如何做!!!

program EigntNumber;
const f1:array[1..3,1..3] of longint=((1,2,3),
(8,0,4),
(7,6,5));
type zz=array[1..3,1..3] of longint;
const fx:array[1..4] of longint=(1,-1,0,0);
fy:array[1..4] of longint=(0,0 ,1, -1);
var b:array[1..2,1..100000] of zz;
t,h:array[1..2] of longint;
pace:array[1..2,1..100000] of longint;
i,j:Longint;
ch:char;
f:zz;
function pd(h,l:longint):boolean;
begin
if h>3 then exit(false);
if h<=0 then exit(false);
if l>3 then exit(false);
if l<=0 then exit(false);
exit(true);
end;

function check(z:zz; a:longint):longint;
var i:longint;
begin
if a=2 then a:=1 else a:=2;
for i:=1 to t[a] do
if comparedword(b[a,i],z,9)=0 then exit(pace[a,i]);
exit(0);
end;

function kg(z:zz; a:longint):boolean;//应该有优化,但是我不会写
var i:Longint;
begin
for i:=1 to t[a] do
if comparedword(b[a,i],z,9)=0 then exit(false);
exit(true);
end;

procedure expend(a:longint);
var i,j,x,y:longint;
z:zz;

begin
inc(h[a]);
for i:=1 to 3 do
for j:=1 to 3 do
if b[a][h[a]][i][j]=0 then
begin
x:=i;
y:=j;
break;
end;
for i:=1 to 4 do
if pd(x+fx[i],y+fy[i]) then
begin
z:=b[a,h[a]];
z[x,y]:=z[x+fx[i],y+fy[i]];
z[x+fx[i],y+fy[i]]:=0;
if check(z,a)<>0 then
begin
writeln(check(z,a)+pace[a,h[a]]+1);
halt;
end;
if kg(z,a) then
begin
inc(t[a]);
b[a,t[a]]:=z;
pace[a,t[a]]:=pace[a,h[a]]+1;
end;
end;
end;

begin
for i:=1 to 3 do
for j:=1 to 3 do
begin
read(ch);
f[i,j]:=ord(ch)-48;
end;

b[1,1]:=f;
b[2,1]:=f1;
t[1]:=1;
t[2]:=1;
while (h[1]<=t[1]) or (h[2]<=t[2]) do
begin
if (t[1]<=t[2]) and (h[1]<=t[1])then
begin
expend(1);
continue;
end;
if (t[1]>=t[2]) and (h[2]<=t[2]) then
begin
expend(2);
continue;
end;
if h[1]<=t[1] then
expend(1);
if h[2]<=t[2] then
expend(2);
end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: