八数码难题
2015-08-17 20:08
330 查看
题目描述 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*的算法……不造如何做!!!
program EigntNumber; const f1:array[1..3,1..3] of longint=((1,2,3), (8,0,4), (7,6,5)); type zz=array[1..3,1..3] of longint; const fx:array[1..4] of longint=(1,-1,0,0); fy:array[1..4] of longint=(0,0 ,1, -1); var b:array[1..2,1..100000] of zz; t,h:array[1..2] of longint; pace:array[1..2,1..100000] of longint; i,j:Longint; ch:char; f:zz; function pd(h,l:longint):boolean; begin if h>3 then exit(false); if h<=0 then exit(false); if l>3 then exit(false); if l<=0 then exit(false); exit(true); end; function check(z:zz; a:longint):longint; var i:longint; begin if a=2 then a:=1 else a:=2; for i:=1 to t[a] do if comparedword(b[a,i],z,9)=0 then exit(pace[a,i]); exit(0); end; function kg(z:zz; a:longint):boolean;//应该有优化,但是我不会写 var i:Longint; begin for i:=1 to t[a] do if comparedword(b[a,i],z,9)=0 then exit(false); exit(true); end; procedure expend(a:longint); var i,j,x,y:longint; z:zz; begin inc(h[a]); for i:=1 to 3 do for j:=1 to 3 do if b[a][h[a]][i][j]=0 then begin x:=i; y:=j; break; end; for i:=1 to 4 do if pd(x+fx[i],y+fy[i]) then begin z:=b[a,h[a]]; z[x,y]:=z[x+fx[i],y+fy[i]]; z[x+fx[i],y+fy[i]]:=0; if check(z,a)<>0 then begin writeln(check(z,a)+pace[a,h[a]]+1); halt; end; if kg(z,a) then begin inc(t[a]); b[a,t[a]]:=z; pace[a,t[a]]:=pace[a,h[a]]+1; end; end; end; begin for i:=1 to 3 do for j:=1 to 3 do begin read(ch); f[i,j]:=ord(ch)-48; end; b[1,1]:=f; b[2,1]:=f1; t[1]:=1; t[2]:=1; while (h[1]<=t[1]) or (h[2]<=t[2]) do begin if (t[1]<=t[2]) and (h[1]<=t[1])then begin expend(1); continue; end; if (t[1]>=t[2]) and (h[2]<=t[2]) then begin expend(2); continue; end; if h[1]<=t[1] then expend(1); if h[2]<=t[2] then expend(2); end; end.
相关文章推荐
- NAND flash和NOR flash的区别详解
- 阿里云不能启动docker
- 青蛙跳台阶的算法
- Fragment
- Codeforces Gym 100431D Bubble Sort 水题乱搞
- Expressions
- UIMenuController 的使用指南
- kafka的安装和配置
- 算法竞赛入门经典:第七章 暴力求解法 7.4双基回文数
- 算法竞赛入门经典:第七章 暴力求解法 7.3分数拆分
- 8 个不得不说的 MySQL 陷阱
- underscore概况
- 关闭iptables和SELINUX
- CMake 学习
- java环境配置
- 如何提醒客户重载父类的指定方法?
- 装饰者模式(decorator pattern)
- 煤炭行业:如何实现自我救赎?
- HDOJ 2066 一个人的旅行(最短路--dijkstra)
- mongdb 复制集+仲裁(带权限认证)