zoukankan      html  css  js  c++  java
  • 八数码难题 (codevs 1225)题解

    【问题描述】

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

    【样例输入】

        283104765

    【样例输出】

         4

    【解题思路】

         这题要求最少步数,因此为广度优先搜索,用队列实现。最简单的方法就是直接将每种状态存入3×3的数组中,然后将空格往四个方向移动,直至目标状态。

        不过,让我们来看一看样例。

        按往常来说,如果是存入3×3的数组中,那么样例中应该是  2 8 3      

                                                                                 1 0 4

                                                                                 7 6 5 

        可是,样例却是一串数字,且中间没有空格,那么,这就给了我们一种思路,以字符串的形式存入,然后搜索,与目标状态比较时也方便一些。那么我们就换成字符串来搜索,但是字符串中要注意一下,第三位不能移到第四位,第四位不能移到第三位,因此,我们需要对该数字进行判断,看它属于哪一列,然后再搜索。

        不过,这两种方式都会超时(在输出结果的步数比较大的时候),因此,我们需要判重,然而,直接开一个12345678-876543210的布尔型数组会超时,所以,这里我们用到了哈希优化。

    【代码实现】

      1 type rec=record
      2      s:string;
      3      s1,dep:longint;
      4 end;
      5 const di:array[1..4] of longint=(-1,-3,3,1);
      6       c:string='123804765';
      7 var a:array[1..100000] of rec;
      8     b:string;
      9     f,r,i,j,k,x:longint;
     10     flag:array[1..1000010] of boolean;
     11 procedure bfs;
     12 var si:char;
     13     i,j,k:longint;
     14 begin
     15  while f<r do
     16   begin
     17    inc(f);
     18    case a[f].s1 of//判断数字属于哪一列
     19     2,5,8:
     20      for i:=1 to 4 do
     21       if (a[f].s1+di[i]>=1)and(a[f].s1+di[i]<=9) then
     22        begin
     23         inc(r);
     24         a[r]:=a[f];
     25         a[r].s[a[r].s1]:=a[r].s[a[r].s1+di[i]];
     26         a[r].s[a[r].s1+di[i]]:='0';
     27         a[r].s1:=a[r].s1+di[i];
     28         inc(a[r].dep);
     29         val(a[r].s,x);
     30         if not(flag[x mod 1000009]) then
     31          dec(r)
     32         else
     33          begin
     34           flag[x mod 1000009]:=false;
     35           if a[r].s=c then
     36            begin
     37             writeln(a[r].dep);
     38             halt;
     39            end;
     40          end;
     41        end;
     42     1,4,7:
     43      for i:=2 to 4 do
     44       if (a[f].s1+di[i]>=1)and(a[f].s1+di[i]<=9) then
     45        begin
     46         inc(r);
     47         a[r]:=a[f];
     48         a[r].s[a[r].s1]:=a[r].s[a[r].s1+di[i]];
     49         a[r].s[a[r].s1+di[i]]:='0';
     50         a[r].s1:=a[r].s1+di[i];
     51         inc(a[r].dep);
     52         val(a[r].s,x);
     53         if not(flag[x mod 1000009]) then
     54          dec(r)
     55         else
     56          begin
     57           flag[x mod 1000009]:=false;
     58           if a[r].s=c then
     59            begin
     60             writeln(a[r].dep);
     61             halt;
     62            end;
     63          end;
     64        end;
     65     3,6,9:
     66      for i:=1 to 3 do
     67       if (a[f].s1+di[i]>=1)and(a[f].s1+di[i]<=9) then
     68        begin
     69         inc(r);
     70         a[r]:=a[f];
     71         a[r].s[a[r].s1]:=a[r].s[a[r].s1+di[i]];
     72         a[r].s[a[r].s1+di[i]]:='0';
     73         a[r].s1:=a[r].s1+di[i];
     74         inc(a[r].dep);
     75         val(a[r].s,x);
     76         if not(flag[x mod 1000009]) then
     77          dec(r)
     78         else
     79          begin
     80           flag[x mod 1000009]:=false;
     81           if a[r].s=c then
     82            begin
     83             writeln(a[r].dep);
     84             halt;
     85            end;
     86          end;
     87        end;
     88     end;
     89   end;
     90 end;
     91 begin
     92  fillchar(flag,sizeof(flag),true);
     93  readln(a[1].s);
     94  for i:=1 to 9 do
     95   if a[1].s[i]='0' then
     96    begin
     97     a[1].s1:=i;
     98     break;
     99    end;
    100  f:=0;r:=1;
    101  bfs;
    102 end.
  • 相关阅读:
    bzoj [POI2015]Myjnie
    bzoj2217 [Poi2011]Lollipop
    Codeforces A Mist of Florescence
    bzoj4380 [POI2015]Myjnie
    bzoj4292 [PA2015]Równanie
    bzoj 3517翻硬币
    模块补充
    python解释器
    __file__、__name__、__dict__方法整理
    软件开发规范
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4510684.html
Copyright © 2011-2022 走看看