vijos P1360 八数码问题
2014-10-28 15:26
225 查看
背景
Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.
描述
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
格式
输入格式
输入初试状态,一行九个数字,空格用0表示输出格式
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)
样例1
样例输入1[复制]
283104765
样例输出1[复制]
4
题解
A*,上次《骑士精神》是好久以前的了,现在大概理解更深了,大约要自己假设一个可行解(为了最优可以从小到大枚举之类的),至于枚举的上下界,可以大约估计因为有个东西叫“估价函数”。在dfs中也掰一掰,决定是否搜索即可。
#include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<cmath> #include<algorithm> #define maxans 100//4*3*3*3=98 using namespace std; int a[3][3],sx,sy,ans; char ch[15]; int b[3][3]={{1,2,3}, {8,0,4}, {7,6,5} }, xd[9]={1,0,0,0,1,2,2,2,1}, yd[9]={1,0,1,2,2,2,1,0,0}; int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0}; void init() { scanf("%s",ch); int i; for(i=0;i<9;i++) {a[i/3][i%3]=ch[i]-'0'; if(a[i/3][i%3]==0) {sx=i/3; sy=i%3;} } } bool check(int A[3][3]) { int i,j; for(i=0;i<3;i++) for(j=0;j<3;j++) {if(A[i][j]!=b[i][j]) return false;} return true; } bool eval(int A[3][3],int x,int y,int s,int tot) { int i,j,ct=0; for(i=0;i<3;i++) for(j=0;j<3;j++) {if(i==x&&j==y) continue; ct+=abs(i-xd[A[i][j]])+abs(j-yd[A[i][j]]); if(ct+s>tot) return false; } return true; } void dfs(int A[3][3],int xn,int yn,int ct,int tot) { if(ct==tot) {if(check(A)) ans=1; return ; } if(ans) return; int i,xt,yt; for(i=0;i<4;i++) {xt=xn+xx[i]; yt=yn+yy[i]; if(xt<0||yt<0||xt>2||yt>2) continue; swap(A[xn][yn],A[xt][yt]); if(eval(A,xt,yt,ct,tot)) dfs(A,xt,yt,ct+1,tot); swap(A[xn][yn],A[xt][yt]); } } int main() { init(); int i,j,minb=0; for(i=0;i<3;i++) for(j=0;j<3;j++) {if(i==sx&&j==sy) continue; minb+=abs(i-xd[a[i][j]])+abs(j-yd[a[i][j]]); } for(i=minb;i<=maxans;i++) {dfs(a,sx,sy,0,i); if(ans) {printf("%d\n",i); break ;} } return 0; }
相关文章推荐
- 八数码问题——A*搜索
- 八数码问题
- A*算法在八数码问题上的应用
- 八数码问题之盲目式搜索法(双向搜索法)
- 趣味编程:用BGL求解八数码问题(A*)
- 8 Puzzle/8 数码问题
- 八数码问题分析
- pku 1077 Eight 经典8数码问题 单向BFS + A* BFS + 双向BFS
- 用java语言实现八数码问题--广度优先搜索
- 用java实现人工智能中的A*算法求8数码问题
- 八数码问题的三种算法解答(C#源代码)
- ZJU2004 Commedia dell'arte - 八数码问题有解的条件及其推广
- 八数码问题
- 八数码问题的三种算法解答(C#源代码) (补充)
- 八数码问题完全版-是否可解判断及求解
- 十五数码问题
- 八数码问题(启发式搜索)
- 启发式搜索程序设计-八数码问题
- 数码城竞选海报问题;空间换时间;类似于哈希表的思想一样;过一阵贴上另一种的算法;
- 八数码问题