zoukankan      html  css  js  c++  java
  • 黑白棋游戏 (codevs 2743)题解

    【问题描述】

         黑白棋游戏的棋盘由4×4方格阵列构成。棋盘的每一方格中放有1枚棋子,共有8枚白棋子和8枚黑棋子。这16枚棋子的每一种放置方案都构成一个游戏状态。在棋盘上拥有1条公共边的2个方格称为相邻方格。一个方格最多可有4个相邻方格。在玩黑白棋游戏时,每一步可将任何2个相邻方格中棋子互换位置。对于给定的初始游戏状态和目标游戏状态,编程计算从初始游戏状态变化到目标游戏状态的最短着棋序列。

    【样例输入】

        1111

        0000

        1110

        0010

        1010

        0101

        1010

        0101

    【样例输出】  

        4

        1222

        1424

        3242

        4344

    【解题思路】

         看到最少步数,果断广搜。不过状态太多,需要判重。大家可以看到,出题人在数据一栏写了必须用状态压缩,不能用康托展开和hash,他说往东走,咱们偏往西走,就用hash优化。(别想从我嘴里套出我不会状态压缩和康托展开)不过hash函数会很不好找,这里我用的是二进制转十进制的方法存hash,这样的话保证每种状态下只有一个hash函数,就不需要挂链表了,主要的是比较目前状态与目标状态是否相同时会耗费点时间,不过1s还是能过的,然后一个关键的地方就是存储哪两个坐标换了位置,我是用的字符来存的,详见代码。

    【代码实现】

      1 type arr=array[1..5,1..5] of char;
      2      rec=record
      3      m:arr;
      4      step:longint;
      5      ans:array[1..100,1..5] of char;
      6 end;
      7 const dx:array[1..4] of longint=(1,-1,0,0);
      8       dy:array[1..4] of longint=(0,0,-1,1);
      9 var start,ans:rec;
     10     f:array[0..200000] of boolean;
     11     spos,epos:arr;
     12     fr,r,i,j:longint;
     13     a:array[1..200000] of rec;
     14 function equal(m:arr):boolean;
     15 var i,j:longint;
     16 begin
     17  for i:=1 to 4 do
     18   for j:=1 to 4 do
     19    if m[i,j]<>epos[i,j] then exit(false);
     20  exit(true);
     21 end;
     22 function hash(m:arr):longint;//二进制转十进制,用位运算,效率高
     23 var res,i,j:longint;
     24 begin
     25  res:=0;
     26  for i:=1 to 4 do
     27   for j:=1 to 4 do
     28    begin
     29     res:=(res shl 1);
     30     res:=res+ord(m[i,j])-ord('0');
     31    end;
     32  exit(res);
     33 end;
     34 procedure bfs;
     35 var t,i,j,k,x,y:longint;
     36     now,next:rec;
     37     temp:char;
     38 begin
     39  fillchar(f,sizeof(f),true);
     40  t:=hash(spos);
     41  f[t]:=false;
     42  fr:=0;r:=1;
     43  while fr<>r do
     44   begin
     45    inc(fr);
     46    now:=a[fr];
     47    if equal(now.m) then
     48     begin
     49      ans:=now;
     50      exit;
     51     end;
     52    for i:=1 to 4 do
     53     for j:=1 to 4 do
     54      for k:=1 to 4 do
     55       begin
     56        next:=now;
     57        inc(next.step);
     58        x:=i+dx[k];
     59        y:=j+dy[k];
     60        if (x>=1)and(x<=4)and(y>=1)and(y<=4) then
     61         begin
     62          temp:=next.m[i,j];
     63          next.m[i,j]:=next.m[x,y];
     64          next.m[x,y]:=temp;
     65          next.ans[next.step,1]:=chr(ord('0')+i);
     66          next.ans[next.step,2]:=chr(ord('0')+j);
     67          next.ans[next.step,3]:=chr(ord('0')+x);
     68          next.ans[next.step,4]:=chr(ord('0')+y);
     69          next.ans[next.step,5]:=#0;//存储哪两个坐标换了位置
     70          if equal(next.m) then
     71           begin
     72            ans:=next;
     73            exit;
     74           end;
     75          t:=hash(next.m);
     76          if f[t] then
     77           begin
     78            f[t]:=false;
     79            inc(r);
     80            a[r]:=next;
     81           end;
     82         end;
     83       end;
     84    end;
     85 end;
     86 begin
     87  for i:=1 to 4 do
     88   begin
     89    for j:=1 to 4 do
     90     read(spos[i,j]);
     91    readln;
     92   end;
     93  for i:=1 to 4 do
     94   begin
     95    for j:=1 to 4 do
     96     read(epos[i,j]);
     97    readln;
     98   end;
     99  for i:=1 to 4 do
    100   for j:=1 to 4 do
    101    start.m[i,j]:=spos[i,j];
    102  start.step:=0;
    103  a[1]:=start;
    104  bfs;
    105  writeln(ans.step);
    106  for i:=1 to ans.step do
    107   begin
    108    for j:=1 to 4 do
    109     write(ans.ans[i,j]);
    110    writeln;
    111   end;
    112 end.
  • 相关阅读:
    我是怎么找到电子书的

    task1
    centos7 部署 nginx+tomcat+MariaDB 环境并安装安全狗,使用natapp隧道
    CentOS 7.0 使用 yum 安装 MariaDB 与 MariaDB 的简单配置
    mysql 配置 root 远程访问
    tomcat 配置 https 证书
    how2j 的shiro教程初探
    springboot 设置 session 过期时间
    mybatis 异常 too many connections 解决方案 mysql
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4518105.html
Copyright © 2011-2022 走看看