几个世纪前,亚瑟王和圆桌骑士过去每年在元旦见面,以庆祝他们的团聚。为了纪念这些事件,我们考虑一个棋手游戏,一个棋子国王和几个骑士棋子放在一个方格内,而没有两个骑士会在同一个方格内。
该示例板是标准的8x8正方形阵列:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5cf46b6f0cfe32a055e86d4cd63d1804.gif#pic_center)
国王可以移动到任何相邻的方格中去,只要它不落到棋盘方格外:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/870d4f76a30c29148fe06f2fe2a18c3d.gif#pic_center)
骑士可以跳跃下图所示方格中,只要落到棋盘方格外:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/236b6912e877dbb1fafb64219e76d951.gif#pic_center)
在游戏过程中,玩家可以在同一方格中放置多个棋子。假定方格足够大,它永远不会成为任何其他块自由移动的障碍。
玩家的目标是移动棋子,以便以最少步数移动国王和骑士,并将它们集中在一个方格中。为此,他必须按照上述规则移动国王和骑士。另外,每当国王和一个或多个骑士放置在同一方格中时,玩家都可以选择将国王和某个骑士一起移动,一直随骑士最后一个集中方格中。骑士与国王一起移动骑士时,只计算骑士的步数。
编写一个程序来计算玩家为产生聚会而必须执行的最小移动步数。他们可以集中在任何一个方格中。
程序名称:camelot
输入格式
第1行: 两个以空格分隔的整数:R,C,板上的行数和列数。最多不超过26列,最多不超过30行。
第2行:一直到最后: 输入文件包含一系列用空格分隔的字母/数字对,每行1个或更多。第一对代表国王所在方格的位置;随后的每对代表骑士的位置。可能有0位骑士,也可能骑士可能会填满这个棋盘。行号从1开始编号;列号是以’A’开头的大写字符。
输入示例(文件camelot.in)
8 8
D 4
A 3 A 8
H 1 H 8
国王位于D4。有四个骑士,分别位于A3,A8,H1和H8。
输出格式
一行表示集中到一起所需要的最小移动步数。
输出示范(文件camelot.out)
10
输出示范详细说明
他们集中在B5方格中。
骑士1:A3-B5(1步)
骑士2:A8-C7-B5(2步)
骑士3:H1-G3-F5-D4(接国王)-B5(4步)
骑士4:H8-F7- D6-B5(3步)
1 + 2 + 4 + 3 = 10步
解题算法思路:
国王和骑士可能集中在任何一个方格中。
采用BFS算法,计算骑士们到达棋盘每个方格所需要的步数。计算过程中,同时记录下所有的路径。
对于每个方格,计算所有骑士到达这个方格所需要的步数,得到总步数。
对于国王与骑士汇合步数计算。对于每个方格,BFS计算中记录了每个骑士到达这个方格的路径,在这些路径上找到最接近骑士的方格,得到国王与每个骑士汇合的步数。
注意:国王从(x1,y1)到达(x2,y2)的距离为max(abs(x1-x2),abs(y1-y2))。
为了节约计算时间,棋盘每个方格的边在棋盘初始化的时候,预先生成,在每个骑士进行BFS搜索的时候,可以更加方便使用。
棋盘方格全部使用一位数组计算,提供速度。
同时注意处理一下特殊情况:只有国王的情况下,不需要移动,步数为0。
源代码
/*
ID:
LANG: C++11
PROG: camelot
*/
#include <fstream>
#include <vector>
#include <queue>
#include <cmath>
#include <map>
#include <iostream>
#include <string>
#include <algorithm>
//#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define MAX_R 30
#define MAX_C 26
int R,C;
int king, knight[MAX_R*MAX_C];
int knightNum;
ifstream fin("camelot.in");
ofstream fout("camelot.out");
struct Node {
int x;
int y;
int isVisit;
int knightMoves[8];
};
struct Point {
int x;
int y;
};
Point knightOffset[8] = {
{
-1,-2},{
-1,2},{
-2,-1},{
-2,1},{
1,-2},{
1,2},{
2,-1},{
2,1} };
class Chess {
int rsize,csize;
Node *grid;
public:
Chess(int rsz, int csz) {
rsize = rsz; csize = csz;
grid = (Node *)malloc(rsize*csize * sizeof(Node)