/*
单纯bfs求最短路径,骑士游历系列题目之一
输入:
3 -> 测试例数目
8 -> 棋盘边长
0 0 -> 起始方格
7 0 -> 目的方格
100
0 0
30 50
10
1 1
1 1
输出:
5
28
0
*/
#include <iostream>
#include <queue>
#include <cstring>
namespace {
using namespace std;
struct POS_S {
POS_S(int, int);
int x, y;
};
POS_S::POS_S(int pos_x, int pos_y)
{
x = pos_x; y = pos_y;
}
#define L_MAX 300
int moves[L_MAX][L_MAX]; // 访问标志与距离数组合并. 凡是未访问过的元素均置'无穷大'
#define MOVES_INFINITE (L_MAX * L_MAX)
int l, src_x, src_y, dst_x, dst_y;
// 骑士可以移动的坐标差
int dx[] = {-2, -1, 1, 2, 2, 1, -1, -2}, dy[] = {-1, -2, -2, -1, 1, 2, 2, 1};
inline bool onboard(int x, int y)
{
return (0<=x && x<l) && (0<=y && y<l);
}
inline bool goal(int x, int y)
{
return (x==dst_x) && (y==dst_y);
}
inline bool visited(int x, int y)
{
return moves[x][y] != MOVES_INFINITE; // 利用距离判断是否已经访问过该点
}
void move_reset()
{
for (int i=0; i<l; i++)
{
for (int j=0; j<l; j++)
{
moves[i][j] = MOVES_INFINITE;
}
}
}
int knight_move(int sx, int sy)
{
move_reset();
moves[sx][sy] = 0;
queue<POS_S> Q; // bfs实现依赖队列
Q.push(POS_S(sx, sy));
while (!Q.empty())
{
POS_S pos = Q.front(); Q.pop();
if (goal(pos.x, pos.y))
{
return moves[pos.x][pos.y];
}
for (int i=0; i<8; i++)
{
int nx = pos.x + dx[i];
int ny = pos.y + dy[i];
if (onboard(nx, ny) && !visited(nx, ny))
{
moves[nx][ny] = moves[pos.x][pos.y] + 1;
Q.push(POS_S(nx, ny));
}
}
}
return MOVES_INFINITE;
}
}
int main()
{
int n;
cin >> n;
for (int i=0; i<n; i++)
{
cin >> l;
cin >> src_x >> src_y;
cin >> dst_x >> dst_y;
cout << knight_move(src_x, src_y) << endl;
}
return 0;
}
poj 1915 骑士游历问题
最新推荐文章于 2023-11-09 19:59:54 发布