中国象棋中的跳马问题
时间限制: 2 Sec 内存限制:128 MB
现在棋盘的大小不一定,由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!
思路:一开始把马的起始点加入队列,然后用广搜的思想把此点能到达的其他点加入队列,这里需要一个数组用来记录此点在之前是否已经加入队列,如果加入过队列当中,就不需要再加入了,直到队列里的元素为空,或者搜索到了终点,搜索即停止,然后输出相应答案即可。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
using namespace std;
int p,q;
int sx,sy,ex,ey;
int n,k,vis[111][111];
int hash[111][111];
int dx[]={2,2,-1,1,-2,-2,-1,1};
int dy[]={-1,1,-2,-2,-1,1,2,2};
struct nd
{
int x,y,t;
};
int bfs()
{
nd bmp,bemp;
bemp.x=sx;
bemp.y=sy;
bemp.t=0;
queue<nd>que; //定义一个队列
que.push(bemp); //将bemp进队
while(!que.empty())//队列非空
{
bemp=que.front(); //得到对首元素
que.pop(); //将对首元素出队
if(bemp.x==ex&&bemp.y==ey)
return bemp.t;
int xx;
int yy;
for(int i=0;i<8;i++)
{
int pp=i/2;
if(pp==0)
if(bemp.x+1<=p&&vis[bemp.x+1][bemp.y]==-1)
continue;
if(pp==1)
if(bemp.y-1>=1&&vis[bemp.x][bemp.y-1]==-1)
continue;
if(pp==2)
if(bemp.x-1>=1&&vis[bemp.x-1][bemp.y]==-1)
continue;
if(pp==3)
if(bemp.y+1<=q&&vis[bemp.x][bemp.y+1]==-1)
continue;
xx=bemp.x+dx[i];
yy=bemp.y+dy[i];
if(xx>=1&&xx<=p&&yy>=1&&yy<=q&&vis[xx][yy]==0&&hash[xx][yy]==0)
{
bmp.x=xx;
bmp.y=yy;
bmp.t=bemp.t+1;
que.push(bmp);
hash[xx][yy]=-1;
}
}
}
return -1;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
while(n--)
{
scanf("%d%d",&p,&q);
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
memset(vis,0,sizeof(vis));
memset(hash,0,sizeof(hash));
int i,ox,oy;
scanf("%d",&k);
for(i=0;i<k;i++)
{
scanf("%d %d",&ox,&oy);
vis[ox][oy]=-1;
}
int ans=bfs();
if(ans>=0)
printf("%d\n",ans);
else
printf("can not reach!\n");
}
}
return 0;
}