圆桌骑士问题
很多世纪以前,阿瑟王和他的圆桌武士常在每年元旦聚会庆祝他们的友谊。我们用一个单人玩的棋盘游戏去纪念这个史实:一个国王和多个武士被随机放在8X8的正方形棋盘的不同方格上。只要不越出棋盘,国王可以移至与之相邻的方格内,只要不越出棋盘,武士可以跳日字,在棋局当中,选手可以在同一方格内摆放多个棋子,选手的目标是在尽可能少的步数内把所有的棋子集中到同一方格。为此,他必须按前述方法去移动棋子。此外,当国王和一个或多个武士位于同一方格内时,选手可以选择此后让国王跟随其中一个武士一同向聚会终点移动,就象移动单个武士一样。任务:写出一个程序去计算选手要实现聚会所需最少的移动次数。
输入数据:文件camelot.in包括了以字符串表示的棋盘初始状态。该字符串包含了一串最多有64个不同的棋子位置:首先是国王的位置,而随后是武士们的位置。每个位置由一对字母-数字表示:字母表示棋盘水平坐标,而数字表示棋盘垂直坐标。
输入实例:
D4A3A8H1H8
输出数据:
文件camelot.out必须包含单一的一行,以一个正整数表示选手要实现聚会所需最少的移动次数。
输出实例:
10
输入数据:文件camelot.in包括了以字符串表示的棋盘初始状态。该字符串包含了一串最多有64个不同的棋子位置:首先是国王的位置,而随后是武士们的位置。每个位置由一对字母-数字表示:字母表示棋盘水平坐标,而数字表示棋盘垂直坐标。
输入实例:
D4A3A8H1H8
输出数据:
文件camelot.out必须包含单一的一行,以一个正整数表示选手要实现聚会所需最少的移动次数。
输出实例:
10
分析:枚举+floyd
点——方格
边——马步边、王步边
国王与骑士相遇点:携带点
设D[x1,y1,x2,y2]——任意两点之间的最短路(骑)
proc. 求D值
D[]全置∞
D[x1,y1,x1,y1]置0 //同一点最短路为0
d[]两点之间有马步关系 置1
用Floyd 求D[]的值
主:
min=∞;
枚举“聚集点”
Tot=n个骑士到聚集点的总步数
if tot>=min 则 continue;
枚举n个骑士
枚举携带点位置 //注意:这里枚举点都是两重循环。
if tot-带王骑士到聚集点步数+带国王骑士到“携带点”步数+再到聚集点步数+国王到“携带点”步数<min then 更新;
输出min;
*判断马步关系只需看横坐标绝对值*纵坐标绝对值是否为2
*国王到“携带点”步数=max{横坐标差,纵坐标差}
下面是写得很烂的程序:
Code