【问题描述】

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

【样例输入】

283104765

【样例输出】

4

【解题思路】

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

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

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

1 0 4

7 6 5

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

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

【代码实现】

 type rec=record
s:string;
s1,dep:longint;
end;
const di:array[..] of longint=(-,-,,);
c:string='';
var a:array[..] of rec;
b:string;
f,r,i,j,k,x:longint;
flag:array[..] of boolean;
procedure bfs;
var si:char;
i,j,k:longint;
begin
while f<r do
begin
inc(f);
case a[f].s1 of//判断数字属于哪一列
,,:
for i:= to do
if (a[f].s1+di[i]>=)and(a[f].s1+di[i]<=) then
begin
inc(r);
a[r]:=a[f];
a[r].s[a[r].s1]:=a[r].s[a[r].s1+di[i]];
a[r].s[a[r].s1+di[i]]:='';
a[r].s1:=a[r].s1+di[i];
inc(a[r].dep);
val(a[r].s,x);
if not(flag[x mod ]) then
dec(r)
else
begin
flag[x mod ]:=false;
if a[r].s=c then
begin
writeln(a[r].dep);
halt;
end;
end;
end;
,,:
for i:= to do
if (a[f].s1+di[i]>=)and(a[f].s1+di[i]<=) then
begin
inc(r);
a[r]:=a[f];
a[r].s[a[r].s1]:=a[r].s[a[r].s1+di[i]];
a[r].s[a[r].s1+di[i]]:='';
a[r].s1:=a[r].s1+di[i];
inc(a[r].dep);
val(a[r].s,x);
if not(flag[x mod ]) then
dec(r)
else
begin
flag[x mod ]:=false;
if a[r].s=c then
begin
writeln(a[r].dep);
halt;
end;
end;
end;
,,:
for i:= to do
if (a[f].s1+di[i]>=)and(a[f].s1+di[i]<=) then
begin
inc(r);
a[r]:=a[f];
a[r].s[a[r].s1]:=a[r].s[a[r].s1+di[i]];
a[r].s[a[r].s1+di[i]]:='';
a[r].s1:=a[r].s1+di[i];
inc(a[r].dep);
val(a[r].s,x);
if not(flag[x mod ]) then
dec(r)
else
begin
flag[x mod ]:=false;
if a[r].s=c then
begin
writeln(a[r].dep);
halt;
end;
end;
end;
end;
end;
end;
begin
fillchar(flag,sizeof(flag),true);
readln(a[].s);
for i:= to do
if a[].s[i]='' then
begin
a[].s1:=i;
break;
end;
f:=;r:=;
bfs;
end.

八数码难题 (codevs 1225)题解的更多相关文章

  1. 双向广搜+hash+康托展开 codevs 1225 八数码难题

    codevs 1225 八数码难题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description Yours和zero在研究A*启 ...

  2. Codevs 1225 八数码难题

    1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的 ...

  3. codevs1225八数码难题(搜索·)

    1225 八数码难题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description Yours和zero在研究A*启 ...

  4. 「LuoguP1379」 八数码难题(迭代加深

    [P1379]八数码难题 - 洛谷 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种 ...

  5. [luogu]P1379 八数码难题[广度优先搜索]

    八数码难题 ——!x^n+y^n=z^n 我在此只说明此题的一种用BFS的方法,因为本人也是初学,勉勉强强写了一个单向的BFS,据说最快的是IDA*(然而蒟蒻我不会…) 各位如果想用IDA*的可以看看 ...

  6. 洛谷P1379八数码难题

    题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...

  7. 洛谷 P1379 八数码难题 解题报告

    P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初 ...

  8. 【洛谷P1379】八数码难题(广搜、A*)

    八数码难题 题目描述 一.广搜: 首先要考虑用什么存每一个状态 显然每个状态都用一个矩阵存是很麻烦的. 我们可以考虑将一个3*3的矩阵用一个字符串或long long 存. 每次扩展时再转化为矩阵. ...

  9. 习题:八数码难题(双向BFS)

    八数码难题(wikioi1225) [题目描述] 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出 ...

  10. 洛谷——P1379 八数码难题

    P1379 八数码难题 双向BFS 原来双向BFS是这样的:终止状态与起始状态同时入队,进行搜索,只不过状态标记不一样而已,本题状态使用map来存储 #include<iostream> ...

随机推荐

  1. ibatis cannot find <sql> pattern

    "Could not find SQL statement to include with refid xxx"A: 认真把每个用到xxx的地方都看一遍

  2. cocos2d-lua class 方法解释

    lua中没有类的概念,有的只是表(table),而类之间的继承也就是将父类的表连到了一起,派生类中没有找到的属性和方法就通过元表查找父类,在cocos2d-lua中,封装好的class方法,完美的实现 ...

  3. Grunt 插件使用汇总

    最近使用了很多 Grunt 插件,这里把使用 Grunt 中涉及的从开发.代码检查.单元测试.E2E 测试,直到发布所涉及的插件,做一个比较完全的汇总. 环境搭建 1. 创建 Web 前端开发环境 2 ...

  4. mysq 因断电而导致的错误

    问题来源: 昨天断电,而我没有保存,导致出现以下问题: 2015-10-12 10:48:10 7300 [Note] Plugin 'FEDERATED' is disabled. 2015-10- ...

  5. 如何实现从Android第三方平台推送微信公众号

    最近心血来潮,想要尝试写写有关实现Android平台第三方应用软件去跳转到微信平台的代码.我只是先暂时写写我的思路,如后期实现,便将主要代码附上. 微信公众平台官方宣布微信沟通接口正式上线,用户可以在 ...

  6. MATLAB mex文件

    MATLAB的mex文件是一种特征的函数封装形式,这类函数一般由C/C++语言编写的,经过MATLAB编译器处理而生成的二进制文件.它是可以被MATLAB解释器自动装载并执行的动态链接程序,类似于wi ...

  7. Nodejs文件服务器

    最近一直在忙于一个比较大的项目,在项目中需要有个文件服务器来支持.老鸟们建议我去用NodeJs来实现,我在接手这个项目之前其实并不了解NodeJs,但是一直想去了解.借着这个机会好好去学习一下.下面是 ...

  8. MSP430F149学习之路——按键与LED

    代码 /*********************************** 程序功能:用按键控制LED状态 缺点:按键按下后无法改变LED灯的状态,可以利用板上的复位键^~^ ********** ...

  9. js鼠标,键盘,坐标轴事件

    鼠标按下事件,左键是0,滑轮是1,右键2 document.getElementById("box").onmousedown =function(e) { if (e.butto ...

  10. oracle中,行转列函数wm_concat()结果有长度限制,重写该函数解决

    --Type CREATE OR REPLACE TYPE zh_concat_im AUTHID CURRENT_USER AS OBJECT ( CURR_STR clob, STATIC FUN ...