Description
在一个 n ∗ m n *m n∗m格子的棋盘上,有一只国际象棋的骑士在棋盘的左下角 (1;1)(如图1),骑士只能根据象棋的规则进行移动,要么横向跳动一格纵向跳动两格,要么纵向跳动一格横向跳动两格。 例如, n = 4 , m = 3 n=4,m=3 n=4,m=3时,若骑士在格子(2;1) (如图2), 则骑士只能移入下面格子: ( 1 ; 3 ) , ( 3 ; 3 ) (1;3),(3;3) (1;3),(3;3) 或 ( 4 ; 2 ) (4;2) (4;2);对于给定正整数 n , m , I , j n,m,I,j n,m,I,j值 ( m , n < = 50 , I < = n , j < = m ) (m,n<=50,I<=n,j<=m) (m,n<=50,I<=n,j<=m) ,你要测算出从初始位置 ( 1 ; 1 ) (1;1) (1;1)到格子 ( i ; j ) (i;j) (i;j)最少需要多少次移动。如果不可能到达目标位置,则输出 " N E V E R " "NEVER" "NEVER"。
Input
输入文件的第一行为两个整数n与m,第二行为两个整数i与j。
Output
输出文件仅包含一个整数为初始位置(1;1) 到格子(i;j)最少移动次数。
Sample Input
5 3
1 2
Sample Output
3
解题思路
依然是一道板子题。。。 板子.
只是变成了八个方向。。。
代码
#include<iostream>
#include<cstdio>
using namespace std;
const int dx[9]={0,2,2,1,1,-1,-2,-1,-2};
const int dy[9]={0,-1,1,-2,2,-2,-1,2,1};
int a[100][100],fa[10000],st[10000][3],h,t;//st[][1]记录横坐标,st[][2]表示纵坐标,st[][3]记录步数,fa记录父节点,a记录有没有走过
int n,m,n1,m1;
bool ans=1;
bool check(int x,int y){//是否超界及有没有走过
if(x>0&&x<=n&&y>0&&y<=m&&!a[x][y])
return 1;
else
return 0;
}
void bfs(){
fa[1]=0;
st[1][1]=1;
st[1][2]=1;
st[1][3]=0;
a[1][1]=1;
h=0; t=1;
do{
h++;
for(int k=1;k<=8;k++)
{
if(check(st[h][1]+dx[k],st[h][2]+dy[k]))//判断是否符合
{
t++;
fa[t]=h;
st[t][1]=st[h][1]+dx[k];
st[t][2]=st[h][2]+dy[k];
st[t][3]=st[h][3]+1;
a[st[h][1]+dx[k]][st[h][2]+dy[k]]=1;
if(st[t][1]==n1&&st[t][2]==m1&&st[t][3])//找到直接输出
{ cout<<st[t][3];
ans=0;
h=852852;
t=0;
break;
}
}
}
}while(h<=t);
}
int main(){
cin>>n>>m>>n1>>m1;
bfs();
if(ans)
cout<<"NEVER";//不可能到达目标位置的情况别漏了哟!
}