P1930 亚瑟王的宫殿 Camelot

    • 19通过
    • 53提交
  • 题目提供者JOHNKRAM
  • 标签USACO
  • 难度提高+/省选-

提交  讨论  题解

最新讨论

  • 暂时没有讨论

题目描述

很久以前,亚瑟王和他的骑士习惯每年元旦去庆祝他们的友谊。为了纪念上述事件, 我们把这些故事看作是一个棋盘游戏。有一个国王和若干个骑士被放置在一个由许多方格 组成的棋盘上,没有两个骑士在同一个方格内。

这个例子是标准的 8*8 棋盘

国王可以移动到任何一个相邻的方格,从下图中黑子位置到下图中白子位置前提是他 不掉出棋盘之外。

一个骑士可以从下图中黑子位置移动到下图中白子位置(走“日”字形) 但前提是他 不掉出棋盘之外。

在游戏中,玩家可在每个方格上放不止一个棋子,假定方格足够大,任何棋子都不会 阻碍到其他棋子正常行动。

玩家的任务就是把所有的棋子移动到同一个方格里——用最小的步数。为了完成这个 任务,他必须按照上面所说的规则去移动棋子。另外,玩家可以选择一个骑士跟国王从他 们两个相遇的那个点开始一起行动,这时他们按照骑士的行动规则行动,其他的单独骑士 则自己一直走到集中点。骑士和国王一起走的时候,只算一个人走的步数。

请计算他们集中在一起的最小步数,而且玩家必须自己找出这个集中点。当然,这些 棋子可以在棋盘的任何地方集合。

输入输出格式

输入格式:

第一行: 两个用空格隔开的整数:R,C 分别为棋盘行和列的长。不超过 26 列,40 行。

第二行到结尾: 输入文件包含了一些有空格隔开的字母/数字对,一行有一个或以 上。第一对为国王的位置,接下来是骑士的位置。可能没有骑士,也可能整个棋盘都是骑 士。行从 1 开始,列从大写字母 A 开始。

输出格式:

单独一行表示棋子集中在一个方格的最小步数。

输入输出样例

输入样例#1:

8  8
D 4
A 3 A 8
H 1 H 8
输出样例#1:

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 步

题目翻译来自NOCOW。

USACO Training Section 3.3

分析:这道题是一道很明显的搜索题,因为集合点没告诉,所以要枚举集合点,这样的话涉及到多次计算,先进行预处理,处理每两个点之间距离,因为是无权无向图,用bfs就可以了,如果不考虑骑士背国王的话,只需要把所有骑士的点到集合点的距离加起来并加上国王与集合点的横纵坐标的差的最大值即可(国王可以八个方向走),如果考虑背国王的话,有点麻烦.首先你不知道是哪个骑士背国王,然后不知道在哪背,因为国王也要走动,这样的话枚举背的骑士和背的地点,根据之前预处理好的数组计算即可.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath> using namespace std; int r, c, dis[][][][],num,ans = ; const int dr[] = { -,-,,,,,-,- };
const int dc[] = { ,,,,-,-,-,- }; struct node
{
int r, c;
}king,qishi[]; bool vis[][]; bool check(int x, int y)
{
if (x >= && x <= r && y >= && y <= c)
return true;
return false;
} void bfs(int x,int y) {
int r, c, step;
queue<node> q;
node temp;
temp.r = x;
temp.c = y;
q.push(temp);
memset(vis, false, sizeof(vis));
dis[x][y][x][y] = ;
vis[x][y] = true; while (!q.empty()) {
node u = q.front();
q.pop();
step = dis[x][y][u.r][u.c];
for (int i = ;i<;++i) {
int r = u.r + dr[i];
int c = u.c + dc[i];
if (check(r, c) && !vis[r][c]) {
vis[r][c] = true;
dis[x][y][r][c] = step + ;
node temp;
temp.r = r;
temp.c = c;
q.push(temp);
}
}
}
} int main()
{
scanf("%d%d", &r, &c);
char s[];
int t;
scanf("%s %d", s, &t);
king.r = t;
king.c = s[] - 'A' + ;
while (scanf("%s%d", s, &t) == )
{
qishi[++num].r = t;
qishi[num].c = s[] - 'A' + ;
}
for (int i = ; i <= r; i++)
for (int j = ; j <= c; j++)
for (int k = ; k <= r; k++)
for (int l = ; l <= c; l++)
dis[i][j][k][l] = ;
for (int i = ; i <= r; i++)
for (int j = ; j <= c; j++)
bfs(i, j);
for (int i = ; i <= r; i++)
for (int j = ; j <= c; j++)
{
int temp = ;
for (int k = ; k <= num; k++)
temp += dis[qishi[k].r][qishi[k].c][i][j];
ans = min(ans, temp + max(abs(king.r - i), abs(king.c - j)));
for (int k = ; k <= num; k++)
{
int dx = qishi[k].r, dy = qishi[k].c;
int t = temp - dis[dx][dy][i][j];
if (t >= ans) //最优性剪枝
continue;
for (int l = ; l <= r; l++)
for (int s = ; s <= c; s++)
ans = min(ans, t + dis[l][s][dx][dy] + dis[l][s][i][j] + max(abs(king.r - l), abs(king.c - s)));
}
}
printf("%d\n", ans); return ;
}

洛谷P1930 亚瑟王的宫殿 Camelot的更多相关文章

  1. 洛谷 P1930 亚瑟王的宫殿 Camelot

    传送门 题目大意:棋盘有骑士有王,让所有点跳到一个点,求所有棋子跳的步数和,和最小. 题解:bfs+枚举 王的人生: 1):自己走到聚集点 2):某个骑士来到王这里,两个棋子一起到聚集点 3):王走几 ...

  2. USACO Training3.3亚瑟王的宫殿【搜索】By cellur925

    题目传送门 因为太蒟了,所以参考了dalao@zbtrs ==    对此表示感谢并侵删. 看起来我们就知道这是搜索题. 最后的情况分两种:有骑士背国王/国王自食其力走到集合点. 首先,我们不知道大家 ...

  3. [洛谷 P3239] [HNOI2015]亚瑟王

    [HNOI2015]亚瑟王 题目描述 小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑.他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知, ...

  4. 洛谷 P3239 / loj 2112 [HNOI2015] 亚瑟王 题解【期望】【DP】

    ???看不懂的期望DP 题目描述 小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑. 他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知,亚 ...

  5. 【洛谷3239_BZOJ4008】[HNOI2015] 亚瑟王(期望 DP)

    题目: 洛谷 3239 分析: 卡牌造成的伤害是互相独立的,所以 \(ans=\sum f_i\cdot d_i\) ,其中 \(f_i\) 表示第 \(i\) 张牌 在整局游戏中 发动技能的概率.那 ...

  6. 洛谷P3239 [HNOI2015]亚瑟王

    题目描述 小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑.他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知,亚瑟王是一个看脸的游戏,技能 ...

  7. 【洛谷2403】[SDOI2010] 所驼门王的宝藏(Tarjan+dfs遍历)

    点此看题面 大致题意: 一个由\(R*C\)间矩形宫室组成的宫殿中的\(N\)间宫室里埋藏着宝藏.由一间宫室到达另一间宫室只能通过传送门,且只有埋有宝藏的宫室才有传送门.传送门分为3种,分别可以到达同 ...

  8. 【BZOJ4008】[HNOI2015]亚瑟王(动态规划)

    [BZOJ4008][HNOI2015]亚瑟王(动态规划) 题面 BZOJ 洛谷 题解 设\(f[i][j]\)表示前\(i\)张卡中有\(j\)张被触发的概率. 分两种情况转移,即当前这张是否被触发 ...

  9. 【BZOJ4008】[HNOI2015]亚瑟王

    [BZOJ4008][HNOI2015]亚瑟王 题面 bzoj 洛谷 题解 由期望的线性性 可以知道,把所有牌打出的概率乘上它的伤害加起来就是答案 记第$i$张牌打出的概率为$fp[i]$ 则 $$ ...

随机推荐

  1. .NET常用方法收藏

    1.过滤文本中的HTML标签 /// <summary> /// 清除文本中Html的标签 /// </summary> /// <param name="Co ...

  2. SQL语句技巧_索引的优化_慢查询日志开启_root密码的破解

    1.正则表达式的使用 regexp例:select name,email from t where email regexp '@163[.,]com$'使用like方式查询selct name,em ...

  3. Form_Form Builder开发基于视图页面和自动代码生成包(案例)

     2014-01-06 Created By BaoXinjian

  4. 【JavaScript】JavaScript模拟Class

    beauty("$Class",["$underscore"],function(_){ var Class = function () { var lengt ...

  5. Servlet3.0学习总结(二)——使用注解标注过滤器(Filter)

    Servlet3.0提供@WebFilter注解将一个实现了javax.servlet.Filter接口的类定义为过滤器,这样我们在web应用中使用过滤器时,也不再需要在web.xml文件中配置过滤器 ...

  6. R中根据匹配原则将一列拆分为几列的方法

    例如我们需要将一下数据的第二列从and处拆分为两列: before = data.frame(attr = c(1,30,4,6), type=c('foo_and_bar','foo_and_bar ...

  7. Number of Islands

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  8. arm-linux-objcopy

    被用来复制一个目标文件的内容到另一个文件中,可用于不同源文件的之间的格式转换示例: arm-linux-objcopy –O binary –S file.elf file.bin 常用的选项(大写) ...

  9. arp -s 157.55.85.212 00-aa-00-62-c6-09 .... Adds a static entry.

    ARp是一个重要的TCp/Ip协议,并且用于确定对应Ip地址的网卡物理地址.实用arp命令,我们能够查看本地计算机或另一台计算机的ARp高速缓存中的当前内容.此外,使用arp命令,也可以用人工方式输入 ...

  10. NLog文章系列——如何配置NLog

    NLog支持以多种不同方式配置,目前同时支持直接编程和使用配置文件两种方法.本文将对目前支持的各种配置方式作详细描述. 日志配置 通过在启动的时候对一些常用目录的扫描,NLog会尝试使用找到的配置信息 ...