题目大意:
计算马在棋盘上从一个格到另一个格所走的最少步数,棋盘的行号用数字1 ~ 8表示,棋盘的列用小写字母a ~ h表示(棋盘大小为8×8),现有多个测例(以EOF结束),每个测例的输入只有一行,表示了开始位置和目标位置,形式诸如"e2 c3",表示让你求从2行e列走到3行c列的最少步数。
注释代码:
/*
* Problem ID : POJ 2243 Knight Moves
* Author : Lirx.t.Una
* Language : C++
* Run Time : 79 ms
* Run Memory : 144 KB
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
struct Point {//表示广搜时队列中的状态
char x, y;//棋盘上点的坐标
char stp;//从起始位置到达该位置所走过的步数
Point(void) {}
Point( char xx, char yy, char sstp ) :
x(xx), y(yy), stp(sstp) {}
};
bool vis[9][9];//表示棋盘上的点是否被访问过
//马的8中走法
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
main() {
int i;//计数变量
//start and end,临时接受起点终点坐标的变量
int sx, sy;
int ex, ey;
//临时坐标
int vx, vy;
Point p;//临时点
char c1, c2;//用于结束输入数据
out:while ( ~scanf("\n%c%d %c%d", &c1, &sy, &c2, &ey) ) {
if ( c1 == c2 && sy == ey ) {//特殊情况,起点等于终点
printf("To get from %c%d to %c%d takes %d knight moves.\n",
c1, sy, c2, sy, 0);
continue;
}
memset(vis, false, sizeof(vis));
sx = c1 - 'a' + 1;//转换成好处理的数字坐标
ex = c2 - 'a' + 1;
queue<Point> que;
vis[sx][sy] = true;//起点如队列
que.push( Point( sx, sy, 0 ) );
while ( !que.empty() ) {
p = que.front();
for ( i = 1; i < 9; i++ ) {
vx = p.x + dx[i];
vy = p.y + dy[i];
if ( vx == ex && vy == ey ) {//找到目标
printf("To get from %c%d to %c%d takes %d knight moves.\n",
c1, sy, c2, ey, p.stp + 1);
goto out;
}
if ( vx < 1 || vx > 8 || vy < 1 || vy > 8 || vis[vx][vy] )
continue;//不在棋盘中或已经被访问过
que.push( Point( vx, vy, p.stp + 1 ) );
vis[vx][vy] = true;
}
que.pop();
}
}
return 0;
}
无注释代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
struct Point {
char x, y;
char stp;
Point(void) {}
Point( char xx, char yy, char sstp ) :
x(xx), y(yy), stp(sstp) {}
};
bool vis[9][9];
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
main() {
int i;
int sx, sy;
int ex, ey;
int vx, vy;
Point p;
char c1, c2;
out:while ( ~scanf("\n%c%d %c%d", &c1, &sy, &c2, &ey) ) {
if ( c1 == c2 && sy == ey ) {
printf("To get from %c%d to %c%d takes %d knight moves.\n",
c1, sy, c2, sy, 0);
continue;
}
memset(vis, false, sizeof(vis));
sx = c1 - 'a' + 1;
ex = c2 - 'a' + 1;
queue<Point> que;
vis[sx][sy] = true;
que.push( Point( sx, sy, 0 ) );
while ( !que.empty() ) {
p = que.front();
for ( i = 1; i < 9; i++ ) {
vx = p.x + dx[i];
vy = p.y + dy[i];
if ( vx == ex && vy == ey ) {
printf("To get from %c%d to %c%d takes %d knight moves.\n",
c1, sy, c2, ey, p.stp + 1);
goto out;
}
if ( vx < 1 || vx > 8 || vy < 1 || vy > 8 || vis[vx][vy] )
continue;
que.push( Point( vx, vy, p.stp + 1 ) );
vis[vx][vy] = true;
}
que.pop();
}
}
return 0;
}