题目描述
现在棋盘的大小不一定,由p,q给出,并且在棋盘中将出现障碍物(限制马的行动,与象棋走法相同)
输入
第一行输入n表示有n组测试数据。
每组测试数据第一行输入2个整数p,q,表示棋盘的大小(1<=p,q<=100)。
每组测试数据第二行输入4个整数,表示马的起点位置与终点位置。(位置的取值范围同p,q)
第三行输入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!
提示
此题是一个搜索题,可用DFS或BFS,建议选择BFS(广搜)。一开始把马的起始点加入队列,然后用广搜的思想把此点能到达的其他点加入队列,这里需要一个数组用来记录此点在之前是否已经加入队列,如果加入过队列当中,就不需要再加入了,直到队列里的元素为空,或者搜索到了终点,搜索即停止,然后输出相应答案即可。
这个题目本人主要用的是BFS的方法 把象棋的位置 以及从初始点到该点走的步数弄成一个结构体 然后再使用STL中的队列容器 在oprate函数中 主要分为三个部分 第一个是对首元素入队列 然后就是对头取元素 再扩展。 这里声明一点在main函数注意边界问题 再过一段时间我再写双向BFS 以及DFS代码
#include <iostream> #include <algorithm> #include <queue> #include <stdio.h> using namespace std; int oprate(int a[]); int in(int ,int); typedef struct chess { int x; int y; int mun; }chess; queue<chess>Q; int b[105][105]= {0}; int L[16]={-2,1,-2,-1,-1,-2,1,-2,2,-1,2,1,1,2,-1,2}; int I[16]={-1,0,-1,0,0,-1,0,-1,1,0,1,0,0,1,0,1}; int xx;int yy; int main() { int a[5]; int n,m,k,z,sum; scanf("%d",&n); while(n--) { scanf("%d %d",&xx,&yy); for(int i=0; i<4; i++) scanf("%d",&a[i]); scanf("%d",&m); for(int i=0;i<m;i++) { scanf("%d %d",&k,&z); b[k][z]=2; } sum=oprate(a); if(sum==-1) printf("can not reach!\n"); else printf("%d\n",sum); for(int i=0;i<=xx;i++) for(int j=0;j<=yy;j++) b[i][j]=0; } return 0; } int oprate ( int a[ ] ) { chess d;chess g; d.x=a[0];d.y=a[1];d.mun=0; b[d.x][d.y]=1; Q.push(d); while(!Q.empty()) { d=Q.front();Q.pop(); if(d.x==a[2]&&d.y==a[3]) { while(!Q.empty()) Q.pop(); return d.mun; } for(int i=0;i<8;i++) { if(in(d.x+L[2*i],d.y+L[2*i+1])&&b[d.x+L[2*i]][d.y+L[2*i+1]]==0) { if(b[d.x+I[2*i]][d.y+I[2*i+1]]==2) continue; else { b[d.x+L[2*i]][d.y+L[2*i+1]]=1; g.x=d.x+L[2*i]; g.y=d.y+L[2*i+1]; g.mun=d.mun+1; Q.push(g); } } } } return -1; } int in(int x,int y) { if(x<=xx&&x>0&&y>0&&y<=yy) return 1; else return 0; }