TopCoder: CaptureThemAll BFS算法

题目来源:CaptureThemAll


思路:knight在棋盘每个位置上有三个状态,一是没有吃到rook和queen,二是吃到了rook,没有吃到queen,三是吃到了queen,没有吃到rook,全部吃到的话搜索结束,则knight工共有3 * 64个状态,64为棋盘位置数,故采用BFS算法,代码如下:


之前的代码有一点问题,现修改如下:

/**
 * TopCoder: CaptureThemAll 
 *(http://community.topcoder.com/stat?c=problem_statement&pm=2915&rd=5853)
 * Author: xuzhezhao
 * E-mail: zhezhaoxu@gmail.com
 * Blog: http://blog.csdn.net/xuzhezhaozhao/
 * Date: 2013/6/4
 */

#include <iostream>
#include <string>
#include <queue>

#define ROWS	8
#define COLS	8

#define STATES_NUM	(3 * ROWS * COLS)

using namespace std;

class CaptureThemAll
{
public:
	int fastKnight(string knight, string rook, string queen);
};

typedef struct {
	int pos;
	int steps;
	bool rook_eaten;
	bool queen_eaten;
}vertex;

int getPos(string cr);
vertex jump(vertex vex, int dirction);
int getStateIndex(vertex vex);

int visited[STATES_NUM];

int main()
{
	CaptureThemAll chess;
	string knight = "a1";
	string rook = "a8";
	string queen = "h1";

	for (int i = 0; i < STATES_NUM; i++) {
		visited[i] = false;
	}

	cout << chess.fastKnight(knight, rook, queen) << endl;

	return 0;
}

int CaptureThemAll::fastKnight(string knight, string rook, string queen)
{
	queue<vertex> Q;
	int state;
	vertex vex, vex_next;
	bool rook_eaten, queen_eaten;
	int knight_pos, rook_pos, queen_pos;

	rook_eaten = queen_eaten = false;
	knight_pos = getPos(knight);
	rook_pos = getPos(rook);
	queen_pos = getPos(queen);

	vex.pos = knight_pos;
	vex.steps = 0;
	vex.queen_eaten = vex.rook_eaten = false;
	Q.push(vex);
	while (true) {
		vex = Q.front();
		Q.pop();
		for (int i = 1; i <= 8; i++) {
			vex_next = jump(vex, i);
			if (vex_next.pos > 0) {		/* 没有越棋盘边界 */
				if (vex_next.pos == rook_pos) {
					vex_next.rook_eaten = true;
				} else if (vex_next.pos == queen_pos) {
					vex_next.queen_eaten = true;
				}

				if (vex_next.rook_eaten && vex_next.queen_eaten) {
					return vex_next.steps;
				}
				state = getStateIndex(vex_next);
				if (!visited[state]) {
					visited[state] = true;
					Q.push(vex_next);
				}
			}
		}
	}
}

/**
 * 返回cr表示的棋盘位置的0-63数字表示形式
 */
int getPos(string cr)
{
	return (cr[0] - 'a') * COLS + (cr[1] - '1');
}

/**
 * 得到knight走一步后的位置
 */
vertex jump(vertex vex, int dirction)
{
	int col, row;
	col = vex.pos / COLS;	/* 纵軕 */
	row = vex.pos % ROWS;	/* 横軕 */
	++vex.steps;
	switch (dirction) {
	case 1:		/* 右1上2 */
		col += 1;
		row += 2;
		break;
	case 2:		/* 右2上1 */
		col += 2;
		row += 1;
		break;
	case 3:		/* 右2下1 */
		col += 2;
		row -= 1;
		break;
	case 4:		/* 右1下2 */
		col += 1;
		row -= 2;
		break;
	case 5:		/* 左1下2 */
		col -= 1;
		row -= 2;
		break;
	case  6:	/* 左2下1 */
		col -= 2;
		row -= 1;
		break;
	case 7:		/* 左2上1 */
		col -= 2;
		row += 1;
		break;
	case 8:		/* 左1上2 */
		col -= 1;
		row += 2;
		break;
	}

	if (col > COLS - 1 || row > ROWS - 1 || col < 0 || row < 0) {
		vex.pos = -1;
	} else {
		vex.pos = col * COLS + row;
	}
	return vex;
}

/**
 * 得到当前位置的状态,对于于visited数组,每个棋盘位置对应有3个状态,一是没有吃到rook和
 * queen,二是吃到了rook,没有吃到queen,三是吃到了queen,没有吃到rook。
 */
int getStateIndex(vertex vex)
{
	if (!vex.rook_eaten && !vex.queen_eaten) {
		return (3 * vex.pos);
	} else if (vex.rook_eaten && !vex.queen_eaten) {
		return (3 * vex.pos + 1);
	} else {
		return (3 * vex.pos + 2);
	}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值