圆桌骑士问题

    很多世纪以前,阿瑟王和他的圆桌武士常在每年元旦聚会庆祝他们的友谊。我们用一个单人玩的棋盘游戏去纪念这个史实:一个国王和多个武士被随机放在8X8的正方形棋盘的不同方格上。只要不越出棋盘,国王可以移至与之相邻的方格内,只要不越出棋盘,武士可以跳日字,在棋局当中,选手可以在同一方格内摆放多个棋子,选手的目标是在尽可能少的步数内把所有的棋子集中到同一方格。为此,他必须按前述方法去移动棋子。此外,当国王和一个或多个武士位于同一方格内时,选手可以选择此后让国王跟随其中一个武士一同向聚会终点移动,就象移动单个武士一样。任务:写出一个程序去计算选手要实现聚会所需最少的移动次数。
输入数据:文件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

 

posted @ 2009-11-08 12:07  末日凌晨 散步的猫 ##  阅读(409)  评论(0编辑  收藏  举报