• 八数码难题


    题目描述 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.
  • 相关阅读:
    coder的脚印
    Mysql
    MSDos
    Windows Develop
    Eclipse 使用总结
    DBA常用SQL
    SSH总结
    Unity3D协程
    yield的作用
    UGUI优化
  • 原文地址:https://www.cnblogs.com/wuminyan/p/4737592.html
Copyright © 2020-2023  润新知