您现在的位置是:首页 > 唯美句子

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

作者:言安琪时间:2024-03-23 13:01:05分类:唯美句子

简介  文章浏览阅读1.7k次,点赞6次,收藏8次。3. 遍历完成了,魏国就把所有对自己有利的方案统统纳入麾下,然而这些方案还不能满足魏国,于是,魏国把优势在他的方案拿下后,剩下的兵力统统去协助魏国要面对的逆风局(魏国兵力不足其他两国的方案)。怎么才能使逆风局拿下的多

点击全文阅读

题目描述

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

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

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

输入格式

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

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

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

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

输出格式

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

样例输入

31 2 22 3 21 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. 转换格式。问题的输入是输入三行,每行代表每个国家选择的方案所对应增加的兵力。格式如下:

输入:51 2 3 4 55 6 7 8 96 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:        break    else:        account += i        ans += 1

参考代码

def process(inf, win, fail1, fail2):    # 假想win的一方-其他两个输的,大于0则直接加入,计数+1,为什么不能等于0呢,万一全等于0不能判断其赢。    # 加完后再与小于等于0的加,满足加后大于0,统计加的次数,即为该阵营赢的最大方案。    account = 0#富余的兵力    ans = 0#最大可选的方案    not_want = []#不足的方案统计    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)    #要优先考虑需要补充兵力最少的(贪心),排序,从少到多补充    not_want.sort(reverse=True)    for i in not_want:        if account + i <= 0:            break        else:            account += i            ans += 1    #没有可以获胜的情况    if ans == 0:return -1    return ans#输入n = int(input())inf = []a = list(map(int, input().split()))b = list(map(int, input().split()))c = list(map(int, input().split()))#结合到inf,[[方案一的a,b,c各国征兵情况],[方案二]....]for i in range(n):    inf.append([a[i],b[i],c[i]])print(max(          process(inf,0,1,2),          process(inf,1,0,2),          process(inf,2,0,1)          )      )

运行结果

运行地址icon-default.png?t=N7T8https://www.dotcpp.com/oj/problem3158.html

点击全文阅读

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

我来说两句