前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >原创 | 你追我,如果你追到我……那就算你赢了

原创 | 你追我,如果你追到我……那就算你赢了

作者头像
TechFlow-承志
发布于 2020-09-22 03:10:29
发布于 2020-09-22 03:10:29
44200
代码可运行
举报
文章被收录于专栏:TechFlowTechFlow
运行总次数:0
代码可运行

大家好,欢迎阅读周末算法题专题。

今天选择的算法题来源于昨天同一套题中的D题,这题全场通过的人数在2600人左右。虽然通过的人数更少了一些,但是题目的难度却并没有增加很多,但是趣味度增加了。我也是第一次遇见这样的问题。

题目链接:https://codeforces.com/contest/1405/problem/D

废话不多说,我们一起来看这题的题意。

题意

我们都知道数据结构当中的树有这样一个性质,如果树当中有n个点,那么它应该由n-1条无向边组成。并且树当中是一定没有环的,如果有环的话n-1条边就不够了。

今天是说有两个人分别叫做Alice和Bob在一棵树上玩游戏,这两个人名是业内的惯例。凡是两个人玩游戏的题目,主人公的名字很多都叫Alice和Bob,我也不知道这个惯例的由来,大家知道这么回事就好了。Alice和Bob两人各自占据了树上的一个点,然后两个人交替移动。Alice先手,Bob后手。

Alice每一次移动最多可以移动da距离,Bob最多可以移动db距离,两个人也可以放弃移动。假设两人都绝顶聪明每一次都会选择最佳策略,请问经过最多

10100

个回合之后,Alice能否捉到Bob呢?如果可以则Alice获胜,否则Bob获胜。注意在Bob的回合,它可以经过Alice的节点,这并不会被视为捉到。

不知道为什么看到这道题的时候,总是会想起费玉清的段子,不知道你们有没有这种感觉。

样例

第一行输入一个数t,表示测试数据的组数。

对于每组数据首先有5个数,分别是n, a, b, da, db。n表示树节点的个数,a和b表示游戏开始时a和b出生点的位置。da和db表示Alice和Bob每回合最多移动的距离。这几个数的最大范围都是

105

,并且多组数据当中所有的n相加不超过

105

我们来看两组样例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
4 3 2 1 2
1 2
1 3
1 4
6 6 1 2 5
1 2
6 5
2 3
3 4
4 5

第一组数据是这样的:

蓝色表示Alice,红色是Bob。由于Alice先手,只要Alice移动到1节点,无论Bob如何移动,他都必输无疑。

第二组数据:

由于Alice最多只能移动两格,第一回合移动到3,Bob选择不动。只要Alice移动,不论是一格还是两格,Bob都可以直接移动到1节点。也就是说最终Bob就在1和6节点之间来回移动,躲开Alice的追捕。

题解

看到Alice和Bob两人游戏,并且两人都绝顶聪明会选择最佳策略,首先想到的就是博弈论。但是观察一下你会发现这题和博弈论没有什么关系,因为博弈论往往都是公平博弈,局面会有状态转移。但这题当中不是,这题不存在胜负状态转移,一定会有一个确定的结果,就是是谁胜谁负,所以这题不满足博弈论的前提。

类似博弈论的题面只是障眼法而已,如果你信了,并且真的往这方面努力,那么你就被出题人骗了。不过这个陷阱还是比较明显的,很容易看出来。接下来我们又遇到了另外一个陷阱,这个陷阱也很明显,就是执行的回合数量。题目给的是

10100

,这个数是真正的天文数字,比宇宙当中所有的粒子数都要多。所以我们可以完全可以理解成无限游戏。

如果出题人阴险一点,完全可以给一个

107

这个量级的回合数,会更有欺骗性一些。其实我们想一下就会发现,树上节点最多只有

105

个,当它们玩追逐游戏的时候,只会有两种情况,一种是永远也追不上,还有一种是很快就追上。所以这个回合数没什么意义,就是唬人的。

洞见

首先,第一个洞见是这道题我们使用模拟是不可行的。所谓的模拟也就是模拟题意的运行情况,去一步一步地分析每一个玩家的选择,做出最好的决策,最后得出游戏的结果。不可行的原因也很简单,因为会超时。这个非常明显,就不深入解释了。

除此之外,我们还可以得到其他一些洞见。首先第一个很简单的洞见是,如果Alice和Bob出生的位置相距小于da的话,那么Alice必胜。这个也很好理解,一开始的距离就在Alice的移动范围内,那Bob一上来就被抓住了。没有讨论的余地。另外一个洞见是如果da >= db,那么Alice必胜。

也就是如果Bob跑得比Alice慢的话,他也一样必败。这也很简单,因为地图的范围是有限的,一个追一个逃,逃的速度比追的慢,显然他逃不出去。这个结论虽然简单,但是反过来一想会得到一个问题。如果Bob跑得比Alice快的话,他一定可以获胜吗

我们看第一个案例就知道这个答案不一定,因为地形也会影响最终的结果。树意味着每一个节点都全连通,也意味着每两点的路线只有一条。换句话说每一条路线都是思路,即使Bob跑得快如果不反向跑甩掉Alice的话,那么他也是一样会被Alice追上的。

所以我们接下来要做的就是深入分析这里的情况,把剩下的问题捋清楚。

回味样例

codeforces的问题有一个特点就是我们一定要深入分析样例,因为很多出题人很良心,给出的样例都是关键样例。我们可以借助样例的情况帮助我们分析问题。比如今天说的这题就是一个。

我们来分析一下第一个样例:

这就是典型的Bob跑得比Alice快的样例,Bob不仅跑得比Alice快,甚至还是Alice的两倍。但是我们都知道结果还是Alice获胜,原因也很简单,Alice移动到1号节点之后,Bob只有两个选择要么1号节点要么4号节点,这两个节点都距离1号节点只有一个距离,仍然在Alice追上的范围内。

在这个样例当中Bob的逃跑空间勉强是够的,但还是被追上了,说明他的逃跑速度是不够的。不够的原因也很简单,因为一开始当Alice移动到1节点之后,他距离Bob的距离是1,也就是一个da。这时Bob无路可走只能折返甩开Alice,这时候他最多能够走一个db,他要想不被Alice捉住,首先他需要先走过da这一段距离,接着他需要走出至少da+1的距离,才能保证Alice折返追他也追不到。那么我们可以得出一个条件是db > 2da。

但我们发现仅仅db > 2da还是不够的,因为在这个例子当中我们可以看得出来不够开阔,即使db=3,Bob也没处可去。也就是说在这棵树上至少有一条链路它的长度要大于2da才行,否则即使Bob再能跑也会被地形限制住。对于一棵树而言,求它的最长链路还是比较简单的,我们也在之前的文章当中讲解过,其实就是对于每一个节点都求一个到叶子节点的最长距离和次长距离之和。所有的节点的距离最大的那个就是整棵树上的最长链路。

我们整理一下思路,一共发现了3个条件,只有满足这3个条件,Bob才可能跑掉,否则一定会被Alice捉住。这三个条件分别是:

  1. 起始的时候Bob和Alice距离大于da
  2. 树的直径大于2da
  3. db大于2da

所以我们要求的就只有两点,第一点是一开始它们之间的距离,以及树的直径(树上最长的链路长度)。好在这两点都可以通过递归实现。都理出来了之后代码就不难写了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
t = int(input())

depth = [0 for _ in range(200050)]
for _ in range(t):
    n, a, b, da, db = list(map(int, input().split(' ')))
    edges = [[] for _ in range(n+2)]
    for i in range(n-1):
        u, v = list(map(int, input().split(' ')))
        edges[u].append(v)
        edges[v].append(u)

    diameter = 0

    depth[a] = 0
    def dfs(u, f):
        global diameter
        l = 0
        for v in edges[u]:
            if v == f:
                continue
            # depth数组记录每个节点的树深
            depth[v] = depth[u] + 1
            cur = 1 + dfs(v, u)
            # cur + l即u节点到叶子节点的最长距离和次长距离
            # 直径就是这两者和之中最大的一个
            diameter = max(diameter, cur + l)
            l = max(l, cur)

        return l

 # 以Alice所在的点作为树根,这样depth[b]即Alice和Bob的距离
    dfs(a, -1)
    if depth[b] <= da or da * 2 >= diameter or da*2 >= db:
        print('Alice')
    else:
        print('Bob')

我们把整个思路说穿了是不是有一种一文不值的感觉?但是自己思考要想明白还是不太容易的,codeforces的问题就是这样,经常需要我们在纸上画一画看一看。有时候一些点靠自己想很难完全想明白,但是找一个例子试一试一下就清楚了。这也是codeforces问题有趣的地方之一。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coder梁 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
原创 | codeforces 1451D,一道有趣的博弈论问题
今天选择的问题是Contest 1451场的D题,这是一道有趣简单的伪博弈论问题,全场通过的人有3203人。难度不太高,依旧以思维为主,坑不多,非常友好。
TechFlow-承志
2020/12/08
4270
原创 | codeforces 1451D,一道有趣的博弈论问题
CF1405D「Tree Tag」
Alice and Bob are playing a fun game of tree tag.
hotarugali
2022/03/03
6240
Codeforces Round #668 (Div. 2)A-D
给出一个长度为 n 的排列,排列 p 的定义是,对于任意一个 p[ i ] 来说,其取值范围为 [ 1 , n ] ,且任意两个元素互不相等题目规定函数
ACM算法日常
2020/09/11
5540
Codeforces Round #668 (Div. 2)A-D
博弈专题入门总结(Nim 巴什 SG等证明+例题)
一堆n个物品,两个人轮流从这堆物品中取物, 规定每次取[1,m]个,最后取光者得胜,问先手必胜还是后手必胜。
Here_SDUT
2022/06/29
2K0
博弈专题入门总结(Nim 巴什 SG等证明+例题)
运用「博弈论」分析「先手必胜态」序列具有何种性质,以及如何思考「博弈论」问题
Alice 和 Bob 轮流从黑板上擦掉一个数字,Alice 先手。如果擦除一个数字后,剩余的所有数字按位异或运算得出的结果等于 0 的话,当前玩家游戏失败。 (另外,如果只剩一个数字,按位异或运算得到它本身;如果无数字剩余,按位异或运算结果为 0。)
宫水三叶的刷题日记
2023/01/03
4710
编程之美----NIM游戏
: 博弈游戏·Nim游戏 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 今天我们要认识一对新朋友,Alice与Bob。 Alice与Bob总是在进行各种各样的比试,今天他们在玩一个取石子的游戏。 在这个游戏中,Alice和Bob放置了N堆不同的石子,编号1..N,第i堆中有A[i]个石子。 每一次行动,Alice和Bob可以选择从一堆石子中取出任意数量的石子。至少取1颗,至多取出这一堆剩下的所有石子。 Alice和Bob轮流行动,取走最后一个石子的人获得胜利。 假设每一轮游戏
Gxjun
2018/03/26
1.3K0
只用一行代码就能搞定,博弈论究竟是什么神仙算法?
博弈论是一门很庞大的学科,它算是数学的一个分支,也和运筹学甚至是经济学有关。虽然它严格说起来并不是算法领域的内容,但是有不少关于博弈论有趣的算法和问题。关于博弈的相关理论从很早就已经有了雏形,但是正式构建理论成为一门学科是从计算机之父冯诺依曼开始的。从这点上来说也和计算机有点关系。
TechFlow-承志
2020/06/18
8810
【算法】博弈论(C/C++)
在算法竞赛中,博弈论算法也比较容易出现,一般出了博弈论的题目多少是有点难度的。博弈论算法常用于解决涉及对抗、策略选择、最优决策等问题。这类问题通常涉及两名或多名玩家在某种规则下的竞争,一般每个玩家都绝对聪明试图通过选择最优策略获胜。常见的博弈论问题类型包括零和博弈、格局游戏(如Nim博弈)、棋类游戏以及其他涉及策略选择的问题。下面介绍常见的博弈论算法。
摆烂小白敲代码
2024/10/09
1060
【算法】博弈论(C/C++)
一行代码击败 100% 用户,leetcode 尼姆问题求解
记得还是初中时期,就和同学玩过这样一个游戏。和对手轮流从一堆棋子中取走一个或者多个,最后不能再取的就是输家。
程序员小浩
2020/11/11
8070
AI的博弈论,一份插图教程
我肯定你说对了。对于我们这些早期数学发烧友来说,电影《美丽心灵》(A Beautiful Mind)已经深深地印在了我们的记忆中。Russell Crowe在电影中扮演John Nash,一位诺贝尔经济学奖得主(上图左侧)。
磐创AI
2019/11/29
9120
动态规划入门——动态规划与数据结构的结合,在树上做DP
之前的几篇文章当中一直在聊背包问题,不知道大家有没有觉得有些腻味了。虽然经典的文章当中背包一共有九讲,但除了竞赛选手,我们能理解到单调优化就已经非常出色了。像是带有依赖的背包问题,和混合背包问题,有些剑走偏锋,所以这里不多做分享。如果大家感兴趣可以自行百度背包九讲查看,今天我们来看一个有趣的问题,通过这个有趣的问题,我们来了解一下在树形结构当中做动态规划的方法。
TechFlow-承志
2020/04/14
8240
动态规划入门——动态规划与数据结构的结合,在树上做DP
P1288 取数游戏II
题目描述 有一个取数的游戏。初始时,给出一个环,环上的每条边上都有一个非负整数。这些整数中至少有一个0。然后,将一枚硬币放在环上的一个节点上。两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流取数,取数的规则如下: (1)选择硬币左边或者右边的一条边,并且边上的数非0; (2)将这条边上的数减至任意一个非负整数(至少要有所减小); (3)将硬币移至边的另一端。 如果轮到一个玩家走,这时硬币左右两边的边上的数值都是0,那么这个玩家就输了。 如下图,描述的是Alice和Bob两人的对弈过程,其中黑色节点
attack
2018/04/12
6780
P1288 取数游戏II
漫画:脑筋急转弯题目(尼姆问题求解)
你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。拿掉最后一块石头的人就是获胜者。你作为先手。
程序员小浩
2020/03/30
3650
漫画:脑筋急转弯题目(尼姆问题求解)
博弈论进阶 | 三下五除二解决组合博弈问题的SG函数,究竟是何方神圣?
今天这篇是算法与数据结构专题的第27篇文章,我们继续深入博弈论问题。今天我们要介绍博弈论当中非常重要的一个定理和函数,通过它我们可以解决许多看起来杂乱无章的博弈问题,使得我们可以轻松地解决一大类博弈问题。
TechFlow-承志
2020/07/02
8950
数学知识——博弈论(巴什博奕、尼姆博奕、威佐夫博奕)思路及例题「建议收藏」
在不和小B商量的情况下,作为小A的你是选择招供坐牢5年或0年,还是会选择抵赖坐牢10年或1年呢?
全栈程序员站长
2022/11/04
7.3K0
数学知识——博弈论(巴什博奕、尼姆博奕、威佐夫博奕)思路及例题「建议收藏」
程序员进阶之算法练习(九十五)
题目链接 题目大意: 有n个整数的数组a,现在需要构造一个1到n的排列b; 令𝑐𝑖 = 𝑎𝑖−𝑏𝑖,希望最终𝑐𝑖 出现尽可能多的不同整数。
落影
2024/01/06
1240
程序员进阶之算法练习(九十五)
[LeetCode]动态规划求解博弈问题
博弈论是有趣又有用的知识,可以用来预测在特定的规则下,人们会做出怎样的行为,又会导致怎样的结果。利用博弈论来指导人们的行事法则甚至商业操作,比如著名的囚徒困境就被很好的利用在了商业竞争上。同样,LeetCode也利用博弈论出了几道有意思的题目。
用户6557940
2022/07/24
5920
[LeetCode]动态规划求解博弈问题
LeetCode笔记:Weekly Contest 210 比赛记录
这一次的比赛结果依然是中规中矩,做出来三题,第四题没能搞定,然后排名的话全国202名,全球609名,不算是太挫的成绩,但是也让人开心不起来。
codename_cys
2021/03/26
2980
公平组合游戏-巴什游戏、尼姆游戏和SG函数
公平组合游戏(Impartral Combinatorial Game)是满足以下特征的一类问题:
唔仄lo咚锵
2020/10/09
1.5K0
公平组合游戏-巴什游戏、尼姆游戏和SG函数
2017广东工业大学程序设计竞赛决赛 题解&源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)
心得: 这比赛真的是不要不要的,pending了一下午,也不知道对错,直接做过去就是了,也没有管太多! Problem A: 两只老虎 Description 来,我们先来放松下,听听儿歌,一起“唱”。 两只老虎两只老虎,跑得快跑得快。 一只没有耳朵,一只没有尾巴。 真奇怪,真奇怪。 Tmk也觉得很奇怪,因为在他面前突然出现了一群这样的老虎,有的没耳朵,有的没尾巴,不过也有正常的。 现在Tmk告诉你这群老虎的耳朵个数,尾巴条数,以及老虎的腿的数目,问你有多少只是正常的。 其中只有三种老虎: 第一种(正常的)
Angel_Kitty
2018/04/08
8870
推荐阅读
相关推荐
原创 | codeforces 1451D,一道有趣的博弈论问题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文