【问题描述】

黑白棋游戏的棋盘由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还是能过的,然后一个关键的地方就是存储哪两个坐标换了位置,我是用的字符来存的,详见代码。

【代码实现】

 type arr=array[..,..] of char;
rec=record
m:arr;
step:longint;
ans:array[..,..] of char;
end;
const dx:array[..] of longint=(,-,,);
dy:array[..] of longint=(,,-,);
var start,ans:rec;
f:array[..] of boolean;
spos,epos:arr;
fr,r,i,j:longint;
a:array[..] of rec;
function equal(m:arr):boolean;
var i,j:longint;
begin
for i:= to do
for j:= to do
if m[i,j]<>epos[i,j] then exit(false);
exit(true);
end;
function hash(m:arr):longint;//二进制转十进制,用位运算,效率高
var res,i,j:longint;
begin
res:=;
for i:= to do
for j:= to do
begin
res:=(res shl );
res:=res+ord(m[i,j])-ord('');
end;
exit(res);
end;
procedure bfs;
var t,i,j,k,x,y:longint;
now,next:rec;
temp:char;
begin
fillchar(f,sizeof(f),true);
t:=hash(spos);
f[t]:=false;
fr:=;r:=;
while fr<>r do
begin
inc(fr);
now:=a[fr];
if equal(now.m) then
begin
ans:=now;
exit;
end;
for i:= to do
for j:= to do
for k:= to do
begin
next:=now;
inc(next.step);
x:=i+dx[k];
y:=j+dy[k];
if (x>=)and(x<=)and(y>=)and(y<=) then
begin
temp:=next.m[i,j];
next.m[i,j]:=next.m[x,y];
next.m[x,y]:=temp;
next.ans[next.step,]:=chr(ord('')+i);
next.ans[next.step,]:=chr(ord('')+j);
next.ans[next.step,]:=chr(ord('')+x);
next.ans[next.step,]:=chr(ord('')+y);
next.ans[next.step,]:=#;//存储哪两个坐标换了位置
if equal(next.m) then
begin
ans:=next;
exit;
end;
t:=hash(next.m);
if f[t] then
begin
f[t]:=false;
inc(r);
a[r]:=next;
end;
end;
end;
end;
end;
begin
for i:= to do
begin
for j:= to do
read(spos[i,j]);
readln;
end;
for i:= to do
begin
for j:= to do
read(epos[i,j]);
readln;
end;
for i:= to do
for j:= to do
start.m[i,j]:=spos[i,j];
start.step:=;
a[]:=start;
bfs;
writeln(ans.step);
for i:= to ans.step do
begin
for j:= to do
write(ans.ans[i,j]);
writeln;
end;
end.

黑白棋游戏 (codevs 2743)题解的更多相关文章

  1. 用Dart写的黑白棋游戏

    2013年11月,Dart语言1.0稳定版SDK发布,普天同庆.从此,网页编程不再纠结了. 在我看来,Dart语法简直就是C#的升级版,太像了.之所以喜欢Ruby的一个重要理由是支持mixin功能,而 ...

  2. [CareerCup] 8.8 Othello Game 黑白棋游戏

    8.8 Othello is played as follows: Each Othello piece is white on one side and black on the other. Wh ...

  3. 洛谷 题解 P1225 【黑白棋游戏】

    看见很多dalao写了什么双向BFS,蒟蒻表示不会写啊. 怎么办办? 先来分析一下题目,一眼看去就是一个搜索题,考虑DFS与BFS. 先放一份DFS的代码: #include<bits/stdc ...

  4. BZOJ2319 : 黑白棋游戏

    将01串按1分段,那么分析可得长度为$a$的段拼上长度为$b$的段的SG值为$a-[a\leq b]$. 设$f[i][j][k][l]$表示从后往前用了$i$个1,$j$个0,当前段长度为$k$,后 ...

  5. 洛谷 - P1225 - 黑白棋游戏 - bfs

    神奇bug,没有记录pre就show了,找了1个小时. #include <bits/stdc++.h> using namespace std; #define ll long long ...

  6. Bzoj 2281 [Sdoi2011]黑白棋 题解

    2281: [Sdoi2011]黑白棋 Time Limit: 3 Sec  Memory Limit: 512 MBSubmit: 592  Solved: 362[Submit][Status][ ...

  7. BZOJ 2281: [Sdoi2011]黑白棋 (Nim游戏+dp计数)

    题意 这题目有一点问题,应该是在n个格子里有k个棋子,k是偶数.从左到右一白一黑间隔出现.有两个人不妨叫做小白和小黑.两个人轮流操作,每个人可以选 1~d 枚自己颜色的棋子,如果是白色则只能向右移动, ...

  8. 【BZOJ2281】[SDOI2011]黑白棋(博弈论,动态规划)

    [BZOJ2281][SDOI2011]黑白棋(博弈论,动态规划) 题面 BZOJ 洛谷 题解 先看懂这题目在干什么. 首先BZOJ上面的题面没有图,换到洛谷看题就有图了. 不难发现都相邻的两个异色棋 ...

  9. bzoj 2281 [Sdoi2011]黑白棋(博弈+组合计数)

    黑白棋(game) [问题描述] 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色 ...

随机推荐

  1. [转]整理索引碎片,提升SQL Server速度

    数据库表A有十万条记录,查询速度本来还可以,但导入一千条数据后,问题出现了.当选择的数据在原十万条记录之间时,速度还是挺快的:但当选择的数据在这一千条数据之间时,速度变得奇慢. 凭经验,这是索引碎片问 ...

  2. HDU2063_过山车_C++

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2063 又是一道二分图匹配的裸题,直接上匈牙利算法 注意一点它末尾的0结束,是标志着有多组数据……坑…… # ...

  3. C/c++笔试经典程序(一)

    1.输出结果比较 1) 输出结果:21 2) 输出结果:12.虽然循环只进行了一次,但是对!X++来说,X还是进行了自加运算. 2.指针运算 输出结果8,8.程序运行时,printf语句是从右往左进行 ...

  4. XML Namespace 命名空间

    根据 Namespaces in XML W3C 推荐标准的定义,XML 命名空间 是由国际化资源标识符 (IRI) 标识的 XML 元素和属性集合:该集合通常称作 XML“词汇”. 定义 XML 命 ...

  5. ionic ngcordova map 地圖

    幾乎每個APP都會有地圖 所以在這裏記錄一下 1.在index.html 中 <script src="https://maps.googleapis.com/maps/api/js? ...

  6. LoadRunner性能测试指挥中心Controller 《第四篇》

    一.设计场景 1.设计性能测试场景 Controller有两个视图:设计(Design)视图和运行(Run)视图.启动Controller,在Controller主界面里,我们可以看到这两个视图. 1 ...

  7. HTML中解决双击会选中文本的问题

    HTML中解决双击会选中文本的问题 <div unselectable="on" style="-moz-user-select:none;" onsel ...

  8. 【MySQL】MySQL事务回滚脚本

    MySQL自己的 mysqlbinlog | mysql 回滚不好用,自己写个简单脚本试试: 想法是用mysqlbinlog把需要回滚的事务区域从mysql-bin.file中找到,然后通过脚本再插入 ...

  9. 见怪不怪的typedef

    typedef是C++中的一个十分重要的关键字,它有强大的功能和方法的用途.但是有时候,碰到一些用到typedef的地方却感到很奇怪了. 给个栗子尝尝: typedef void(*pFun)(voi ...

  10. C++ 学习基础一

    1.预处理器指示符如果文件名用尖括号“<”和”>”括起来的,则表示该文件是工程或标准头文件,查找过程会检查预定义的目录.如果文件名用双引号括起来,则表示该文件是用户自定义的头文件,查找该文 ...