Knight Moves
问题
您的任务是编写一个程序,计算骑士从另一个点到达一个点所需的最小动作数量,以便您有机会比索穆罗洛夫更快。
对于不熟悉国际象棋的人,可能的骑士动作显示在图 1 中。
Input
输入从单行上的方案数 n 开始。
接下来关注n个场景。每个方案由包含整数的三行组成。第一行指定了棋盘一侧的长度(4 <=l <= 300)。整个板子都有尺寸l*l。第二行和第三行包含一对整数 [0, …, l-1][0, …, l-1] 指定骑士在棋盘上的开始和结束位置。整数由一个空白隔开。您可以假设该位置是该场景的棋盘上的有效位置。
Output
对于输入的每个场景,您必须计算从起点移动到终点所需的骑士移动的最小数量。如果起点和终点相等,则距离为零。距离必须写在一行上。
Sample Input
3
8
0 0
7 0
100
0 0
30 50
10
1 1
1 1
Sample Output
5
28
0
代码实现
//POJ1915
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int N = 310;
bool vis[N][N];
int dis[N][N];
int dir[8][2] = {{-1,2},{-1,-2},{1,2},{1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
int sx,sy,ex,ey,l;
void BFS(int sx,int sy)
{
queue <pair<int,int>> q; //!!!此行只有写在BFS里才能AC,函数外定义会蛙
q.push(make_pair(sx,sy));
dis[sx][sy] = 0;
while(!q.empty())
{
pair<int,int> now = q.front();
int nx=now.first;
int ny=now.second;
q.pop();
if(nx==ex&&ny==ey) break;
if(vis[nx][ny] == 1) continue;
vis[nx][ny] = 1;
for(int i=0;i<8;i++)
{
int dx=dir[i][0]+nx;
int dy=dir[i][1]+ny;
if(dx>=0&&dx<l&&dy>=0&&dy<l&&vis[dx][dy]==0)
{
dis[dx][dy]=dis[nx][ny] + 1;
q.push(make_pair(dx,dy));
}
}
}
}
int main()
{
int n;
cin>>n;
while(n--)
{
cin>>l;
for(int i=0;i<l;i++)
{
for(int j=0;j<l;j++)
{
vis[i][j] = 0;
dis[i][j] = 1e8;
}
}
cin>>sx>>sy>>ex>>ey;
BFS(sx,sy);
cout<<dis[ex][ey]<<endl;
}
return 0;
}