蓝桥杯笔记-2023年第十四届省赛真题-三国游戏(Python)

03-18 1090阅读

题目描述

小蓝正在玩一款游戏。游戏中魏蜀吴三个国家各自拥有一定数量的士兵X, Y, Z (一开始可以认为都为 0 )。游戏有 n 个可能会发生的事件,每个事件之间相互独立且最多只会发生一次,当第 i 个事件发生时会分别让 X, Y, Z 增加Ai , Bi ,Ci 。

当游戏结束时 (所有事件的发生与否已经确定),如果 X, Y, Z 的其中一个大于另外两个之和,我们认为其获胜。例如,当 X > Y + Z 时,我们认为魏国获胜。小蓝想知道游戏结束时如果有其中一个国家获胜,最多发生了多少个事件?

蓝桥杯笔记-2023年第十四届省赛真题-三国游戏(Python)

如果不存在任何能让某国获胜的情况,请输出 −1 。

输入格式

输入的第一行包含一个整数 n 。

第二行包含 n 个整数表示 Ai,相邻整数之间使用一个空格分隔。

第三行包含 n 个整数表示 Bi,相邻整数之间使用一个空格分隔。

第四行包含 n 个整数表示 Ci,相邻整数之间使用一个空格分隔。

输出格式

输出一行包含一个整数表示答案。

样例输入

3
1 2 2
2 3 2
1 0 7

样例输出

2

提示

发生两个事件时,有两种不同的情况会出现获胜方。

发生 1, 2 事件时蜀国获胜。

发生 1, 3 事件时吴国获胜。

对于 40% 的评测用例,n ≤ 500 ;

对于 70% 的评测用例,n ≤ 5000 ;

对于所有评测用例,1 ≤ n ≤ 105,1 ≤ Ai , Bi ,Ci ≤ 109 。

问题重述

魏,蜀,吴三国分别选择的所有方案最终需要满足(X>Y+Z)该条件,分别找到其可以满足的最大方案数,三国对应的3个最大方案数作为问题输出。如果都没有方案可以使三方其中一个可以获胜,则输出-1。

问题思路

对于假想赢家,要使其胜利,我们可以使用贪心的方法,如何贪心呢?以魏胜利为例:

1. 对于某个方案,如果魏国兵力大于其他两个,说明这个方案必定胜利,而且还有余下的兵力。我们先将剩余的兵力保存,便于不时之需。

2. 把n个方案都遍历一遍,找到符合(1)的方案,统计他们的数量和富余下来的兵力。而打不过的方案,将其记到本本not_want列表上,方便秋后算账。

3. 遍历完成了,魏国就把所有对自己有利的方案统统纳入麾下,然而这些方案还不能满足魏国,于是,魏国把优势在他的方案拿下后,剩下的兵力统统去协助魏国要面对的逆风局(魏国兵力不足其他两国的方案)。怎么才能使逆风局拿下的多呢,我们可以将那些不好的方案按照需要兵力大小进行从小到大排序,给他们一个个的补上,直到剩余兵力快用完,至少留一个(不能全用完,这样就不能赢了,如果最后兵力用完了,只能说明魏国和其他两国打平)。统计打赢的逆风局。

4. 将对应(1)的方案数和(3)的方案数加起来,得到魏国可以打赢需要最大的方案数。以此类推,蜀,吴两国采取同样的方法,得到他们国家最大的方案数,输出三国最大的方案数作为答案。

代码实现

1. 转换格式。问题的输入是输入三行,每行代表每个国家选择的方案所对应增加的兵力。格式如下:

输入:
5
1 2 3 4 5
5 6 7 8 9
6 5 4 3 2
表示:
5(5个方案)
魏 方案1 方案2 方案3 方案4 方案5
蜀 同上
吴 同上

将每个方案魏蜀吴三国对于增加的兵数放在一起(刚开始做的时候以为是每行表示一个方案,发现后破罐子破摔),修改格式后如下:

inf=[[魏方案1,蜀方案1,吴方案1],[魏方案2,蜀方案2,吴方案2],...]

2. 创建需要的参数。

account = 0#富余的兵力
ans = 0#最大可选的方案
not_want = []#不足的方案统计

3. 实现问题思路(2)。

for item in inf:
    total = item[win] - item[fail1] - item[fail2]
    # print(total)
    #if成立说明选这个方案假想winner不但会赢,还会有多出来的兵补给那些方案about假想赢家兵力不足的方案。
    if total > 0:
        account += total
        ans += 1
    #将打不过的方案先屯起来,后面用富余的兵力补充
    else:
        not_want.append(total)

3.实现问题思路(3)。

not_want.sort(reverse=True)
for i in not_want:
    if account + i  0:
            account += total
            ans += 1
        #将打不过的方案先屯起来,后面用富余的兵力补充
        else:
            not_want.append(total)
    #要优先考虑需要补充兵力最少的(贪心),排序,从少到多补充
    not_want.sort(reverse=True)
    for i in not_want:
        if account + i 

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]