BFS:中国象棋中的跳马问题
2015-03-12 20:54
211 查看
问题描述是这样的:
有一张p*q的棋盘,并且棋盘中有障碍物(用来限制马的行动,即中国象棋中的蹩马腿)。有一个棋子马(走“日”字形路线),要从起始点走到终点。
输入部分:
第一行输入一个整数n,表示有n组测试实例,每组测试数据第一行输入两个整数p和q,表示棋盘的大小(1<=p,q<=100),每组测试数据第二行输入4个整数x1,y1,x2,y2,表示马的起点和终点的坐标。第三行输入一个整数m,表示图中有多少障碍物,接着m行每行一个坐标,分别表示m个障碍物的位置坐标。
输出部分:
输出马从起始位置走到终点所需的最小步数。若马不能走到终点,输出“ can not reach!”
样例输入:
2
9 10
1 1 2 3
0
9 10
1 1 2 3
8
1 2
2 2
3 3
3 4
1 4
3 2
2 4
1 3
样例输出
1
can not reach!
分析:对于此题,考虑到要求最小步数,我们选择广搜。先把马的起始点入队,然后用广搜的思想把此点能到达的其他点加入队列,这里需要一个数组s来记录每一点是否已经入队,我们只把那些没有被标记过的点入队,直到队列中的元素为空,或者搜到了终点,搜索结束,然后输出即可。
其实我感觉本题比较有特色的地方就是马的“日”字形走法了,虽然用一个2维数组就能简化,但还要注意和移动方向数组之间的一一对应关系。比如,马开始在(0,0)点,如果(0,1)处有障碍物,那么马就不能走到(-1,2)和(1,2)这两点了,此时方向数组和马的走法数组之间就有(0,-1)和(1,-2)(-1,-2)之间的对应。
实现代码如下:
有一张p*q的棋盘,并且棋盘中有障碍物(用来限制马的行动,即中国象棋中的蹩马腿)。有一个棋子马(走“日”字形路线),要从起始点走到终点。
输入部分:
第一行输入一个整数n,表示有n组测试实例,每组测试数据第一行输入两个整数p和q,表示棋盘的大小(1<=p,q<=100),每组测试数据第二行输入4个整数x1,y1,x2,y2,表示马的起点和终点的坐标。第三行输入一个整数m,表示图中有多少障碍物,接着m行每行一个坐标,分别表示m个障碍物的位置坐标。
输出部分:
输出马从起始位置走到终点所需的最小步数。若马不能走到终点,输出“ can not reach!”
样例输入:
2
9 10
1 1 2 3
0
9 10
1 1 2 3
8
1 2
2 2
3 3
3 4
1 4
3 2
2 4
1 3
样例输出
1
can not reach!
分析:对于此题,考虑到要求最小步数,我们选择广搜。先把马的起始点入队,然后用广搜的思想把此点能到达的其他点加入队列,这里需要一个数组s来记录每一点是否已经入队,我们只把那些没有被标记过的点入队,直到队列中的元素为空,或者搜到了终点,搜索结束,然后输出即可。
其实我感觉本题比较有特色的地方就是马的“日”字形走法了,虽然用一个2维数组就能简化,但还要注意和移动方向数组之间的一一对应关系。比如,马开始在(0,0)点,如果(0,1)处有障碍物,那么马就不能走到(-1,2)和(1,2)这两点了,此时方向数组和马的走法数组之间就有(0,-1)和(1,-2)(-1,-2)之间的对应。
实现代码如下:
#include <iostream> #include <cstring> #include <cstdio> using namespace std; typedef struct node { int x,y,step; }queue; queue que[11000]; int q,p,sx,sy,ex,ey; int map[105][105]; bool s[105][105]; int hdir[8][2]={{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}}; int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};//注意这里要和上面的马的路径相对应 void bfs() { int a=1,b=1; int x,y,hx,hy; que[a].x=sx; que[a].y=sy; que[a].step=0; s[sx][sy]=true; while(a<=b&&!s[ex][ey]) { x=que[a].x; y=que[a].y; for(int i=0;i<8;i++) if(!map[x+dir[i/2][0]][y+dir[i/2][1]]) { hx=x+hdir[i][0]; hy=y+hdir[i][1]; if(hx>0&&hx<=q&&hy>0&&hy<=p&&!s[hx][hy]&&!map[hx][hy]) { b++; que[b].x=hx; que[b].y=hy; que[b].step=que[a].step+1; s[hx][hy]=true; } } a++; } if(a>b) puts("can not reach!"); else printf("%d\n",que[b].step); } int main() { int m,n,a,b; cin>>n; while(n--) { memset(map,0,sizeof(map)); memset(s,false,sizeof(s)); scanf("%d%d",&p,&q); scanf("%d%d%d%d",&sx,&sy,&ex,&ey); scanf("%d",&m); while(m--) { scanf("%d%d",&a,&b); map[a][b]=1; } bfs(); } return 0; }
相关文章推荐
- 中国象棋中的跳马问题(bfs)
- 中国象棋的跳马问题(BFS)
- 课程设计——中国象棋中的跳马问题
- 中国象棋中的跳马问题(学习搜索中)
- 中国象棋中的跳马问题
- 中国象棋中的跳马问题
- 【编程之美】中国象棋将帅问题
- 中国象棋马的遍历问题
- 答案_中国象棋将帅问题
- “中国象棋将帅问题”——自己的解法
- 微软编程之美--中国象棋将帅问题
- 《编程之美》读书笔记01: 1.2中国象棋将帅问题
- 做中国象棋时遇到的问题
- 中国象棋将帅问题——电子书下载
- 中国象棋将帅问题的另类解法
- )《编程之美》读书笔记(一):中国象棋将帅问题
- 编程之美 中国象棋将帅问题 的再进一步讨论
- 面试真题:中国象棋将帅问题
- 《编程之美——微软技术面试心得》“中国象棋的将帅问题”C#实现
- 《编程之美》读书笔记(一):中国象棋将帅问题