题目描述
在一个 n×m个格子的棋盘上,有一只国际象棋的骑士在棋盘的左下角 (1,1)(如图1),骑士只能根据象棋的规则进行移动,要么横向跳动一格纵向跳动两格,要么纵向跳动一格横向跳动两格。 例如, n=4,m=3 时,若骑士在格子 (2,1) (如图 2 ), 则骑士只能移入下面格子:(1,3) , (3,3) 或 (4,2);对于给定正整数 n,m,i,j 值 (m,n<=50,i<=n,j<=m) ,你要测算出从初始位置(1,1) 到格子 (i,j) 最少需要多少次移动。如果不可能到达目标位置,则输出 "NEVER "。
输入
第一行为两个整数 n 与 m ,第二行为两个整数 i 与 j 。
输出
输出仅包含一个整数为初始位置 (1,1) 到格子 (i,j) 最少移动次数。
输入样例
5 3 1 2
输出样例
3
在看到“最少移动次数”时,就能察觉到这题是一道典型的BFS。
从地图的【1】【1】开始,求到【i】【j】的最短路径。
下过象棋的人都知道,马向8个方向移动
路径如下:
在新语法中,是可以用内置队列queue的,只不过要借助结构体struct实现
当然,手敲也是可以的
活不多说,上码:
#include<bits/stdc++.h>
using namespace std;
int n,m,a,b,fx[8][2]={{2,1},{2,-1},{1,2},{1,-2},{-2,-1},{-1,-2},{-2,1},{-1,2}};
bool v[60][60];
struct node
{
int x,y,bs;
} ;
queue<node> q;
int main()
{
cin>>n>>m>>a>>b;
q.push({1,1,0});
v[1][1]=true;
while(!q.empty())
{
node t=q.front();
q.pop();
for(int i=0;i<8;i++)
{
int xx=t.x+fx[i][0],yy=t.y+fx[i][1];
if(xx<1||yy<1||xx>m||yy>n||v[xx][yy])
continue;
v[xx][yy]=true;
q.push({xx,yy,t.bs+1});
if(xx==a&&yy==b)
{
cout<<t.bs+1;
return 0;
}
}
}
cout<<"NEVER";
return 0;
}