八数码难题

题目描述 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*的算法……不造如何做!!!

  1 program EigntNumber;
  2 const f1:array[1..3,1..3] of longint=((1,2,3),
  3                                       (8,0,4),
  4                                       (7,6,5));
  5 type zz=array[1..3,1..3] of longint;
  6 const fx:array[1..4] of longint=(1,-1,0,0);
  7        fy:array[1..4] of longint=(0,0 ,1, -1);
  8 var b:array[1..2,1..100000] of zz;
  9     t,h:array[1..2] of longint;
 10     pace:array[1..2,1..100000] of longint;
 11     i,j:Longint;
 12     ch:char;
 13     f:zz;
 14 function pd(h,l:longint):boolean;
 15 begin
 16     if h>3 then exit(false);
 17     if h<=0 then exit(false);
 18     if l>3 then exit(false);
 19     if l<=0 then exit(false);
 20     exit(true);
 21 end;
 22 
 23 function check(z:zz; a:longint):longint;
 24 var i:longint;
 25 begin
 26     if a=2 then a:=1 else a:=2;
 27     for i:=1 to t[a] do
 28     if comparedword(b[a,i],z,9)=0 then exit(pace[a,i]);
 29     exit(0);
 30 end;
 31 
 32 
 33 function kg(z:zz; a:longint):boolean;//应该有优化,但是我不会写
 34 var i:Longint;
 35 begin
 36     for i:=1 to t[a] do
 37     if comparedword(b[a,i],z,9)=0 then exit(false);
 38     exit(true);
 39 end;
 40 
 41 procedure expend(a:longint);
 42 var i,j,x,y:longint;
 43     z:zz;
 44 
 45 begin
 46     inc(h[a]);
 47     for i:=1 to 3 do
 48         for j:=1 to 3 do
 49         if b[a][h[a]][i][j]=0 then
 50         begin
 51             x:=i;
 52             y:=j;
 53             break;
 54         end;
 55     for i:=1 to 4 do
 56         if pd(x+fx[i],y+fy[i]) then
 57         begin
 58             z:=b[a,h[a]];
 59             z[x,y]:=z[x+fx[i],y+fy[i]];
 60             z[x+fx[i],y+fy[i]]:=0;
 61             if check(z,a)<>0 then
 62             begin
 63                 writeln(check(z,a)+pace[a,h[a]]+1);
 64                 halt;
 65             end;
 66             if kg(z,a) then
 67             begin
 68                 inc(t[a]);
 69                 b[a,t[a]]:=z;
 70                 pace[a,t[a]]:=pace[a,h[a]]+1;
 71             end;
 72         end;
 73 end;
 74 
 75 begin
 76     for i:=1 to 3 do
 77         for j:=1 to 3 do
 78         begin
 79             read(ch);
 80             f[i,j]:=ord(ch)-48;
 81         end;
 82 
 83     b[1,1]:=f;
 84     b[2,1]:=f1;
 85     t[1]:=1;
 86     t[2]:=1;
 87     while (h[1]<=t[1]) or (h[2]<=t[2]) do
 88     begin
 89         if (t[1]<=t[2]) and (h[1]<=t[1])then
 90         begin
 91            expend(1);
 92            continue;
 93         end;
 94         if (t[1]>=t[2]) and (h[2]<=t[2]) then
 95         begin
 96                 expend(2);
 97                 continue;
 98         end;
 99         if h[1]<=t[1] then
100         expend(1);
101         if h[2]<=t[2] then
102         expend(2);
103     end;
104 end.
原文地址:https://www.cnblogs.com/wuminyan/p/4737592.html