POJ 2243 Knight Moves

题目大意:

        计算马在棋盘上从一个格到另一个格所走的最少步数,棋盘的行号用数字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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值