题目大意:
和POJ 2243 Knight Moves一样,也是求马的最少步数,只不过棋盘大小(宽度)n会告诉你(4 ≤ n ≤ 300),而棋盘的行列编号都是(0 ~ n-1),多个测例,测例数已知,每个测例中都给定n以及起始和终止坐标,对于每个测例都输出马的最少步数。
代码:
/*
* Problem ID : POJ 1915 Knight Moves
* Author : Lirx.t.Una
* Language : C++
* Run Time : 282 ms
* Run Memory : 260 KB
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#define MAXN 300
using namespace std;
struct Point {
short x, y;
short stp;
Point(void) {}
Point( short xx, short yy, short sstp ) :
x(xx), y(yy), stp(sstp) {}
};
bool vis[MAXN][MAXN];
char dx[9] = { 0, 1, 1, -1, -1, 2, 2, -2, -2 };
char dy[9] = { 0, 2, -2, 2, -2, 1, -1, 1, -1 };
int n;
int sx, sy;
int ex, ey;
int
bfs(void) {
int i;
int vx, vy;
Point p;
queue<Point> que;
memset(vis, false, sizeof(vis));
vis[sx][sy] = true;
que.push( Point( sx, sy, 0 ) );
while ( !que.empty() ) {
p = que.front();
que.pop();
for ( i = 1; i < 9; i++ ) {
vx = p.x + dx[i];
vy = p.y + dy[i];
if ( vx == ex && vy == ey ) return p.stp + 1;
if ( vx < 0 || vx >= n || vy < 0 || vy >= n || vis[vx][vy] )
continue;
que.push( Point( vx, vy, p.stp + 1 ) );
vis[vx][vy] = true;
}
}
return 0;
}
int
main() {
int t;
scanf("%d", &t);
while ( t-- ) {
scanf("%d%d%d%d%d", &n, &sx, &sy, &ex, &ey);
if ( sx == ex && sy == ey ) {
puts("0");
continue;
}
printf("%d\n", bfs());
}
return 0;
}