在8X8的棋盘上分布着n个骑士,他们想约在某一个格中聚会。骑士每天可以像国际象棋中的马那样移动一次,可以从中间像8个方向移动(当然不能走出棋盘),请计算n个骑士的最早聚会地点和要走多少天。要求尽早聚会

在8X8的棋盘上分布着n个骑士,他们想约在某一个格中聚会。骑士每天可以像国际象棋中的马那样移动一次,可以从中间像8个方向移动(当然不能走出棋盘),请计算n个骑士的最早聚会地点和要走多少天。要求尽早聚会,且n个人走的总步数最少,先到聚会地点的骑士可以不再移动等待其他的骑士。

从键盘输入n(0<n<=64),然后一次输入n个骑士的初始位置xi,yi(0<=xi,yi<=7)。屏幕输出以空格分隔的三个数,分别为聚会点(x,y)以及走的天数。

提示:BFS。

#define M 8
#define N 8
#define DIR 8

typedef struct Pointer {
	int x;
	int y;
};

typedef struct Knight {
	Pointer* point;	//起始点
	bool visited[M][N];	//是否访问
	queue<Pointer*> kq;	//第几天到达的位置
};

//结果结构体
typedef struct Result {
	Pointer* point;
	int days;
};

/*x行,y列
 * 下一步位移*/
int nextX[] = { -1, 1, -2, 2, -2, 2, -1, 1 };
int nextY[] = { -2, -2, -1, -1, 1, 1, 2, 2 };

/*坐标是否合理*/
bool sure(int i, int j) {
	if (i >= 0 && i < M && j >= 0 && j < N)
		return true;
	else
		return false;
}

//寻找集合点和天数
Result* findGatherPoint(vector<Knight*> knights) {
	int days = 0;
	//记录骑士到达数量
	int matrix[M][N] = { 0 };

	if (knights.empty()) {
		return NULL;
	}

	//预处理
	for (int i = 0; i < knights.size(); ++i) {
		matrix[knights[i]->point->x][knights[i]->point->y] = 1;
	}

	while (1) {
		days++;
		for (int i = 0; i < knights.size(); ++i) {
			int len = knights[i]->kq.size();
			for (int j = 0; j < len; ++j) {
				Pointer* tmp = knights[i]->kq.front();
				knights[i]->kq.pop();
				/*BFS向8个方向走一步*/
				for (int k = 0; k < DIR; ++k) {
					int x = tmp->x + nextX[k];
					int y = tmp->y + nextY[k];
					if (sure(x, y) && !knights[i]->visited[x][y]) {
						knights[i]->visited[x][y] = true;
						Pointer* p = new Pointer();
						p->x = x;
						p->y = y;
						knights[i]->kq.push(p);
						matrix[x][y]++;
						if (matrix[x][y] == knights.size()) {
							Result* result = new Result();
							result->point = p;
							result->days = days;
							return result;
						}
					}
				}
			}
		}
	}
}
    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/Edwards_June/article/details/54427485
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞