Python贪心算法——以“「土」巨石滚滚”为例

文章讲述了如何通过贪心算法解决一个关于魔法土球冲撞障碍的问题,关键在于合理安排障碍顺序,优先处理使稳定性增加和减少的障碍,确保土球在不失稳的情况下撞击所有障碍。
摘要由CSDN通过智能技术生成

题目链接:登录—专业IT笔试面试备考平台_牛客网

题目描述

帕秋莉掌握了一种土属性魔法

她使用这种魔法建造了一个大型的土球,并让其一路向下去冲撞障碍

土球有一个稳定性x,如果x < 0,它会立刻散架

每冲撞一个障碍,土球会丧失ai的稳定性,冲撞之后,又会从障碍身上回馈bi的稳定性

帕秋莉想知道,如果合理的安排障碍的顺序,在保证土球不散架的情况下,是否可以将障碍全部撞毁呢?

输入描述 

输入一个整数T,代表T组数据,每组数据中:
前一行两个整数n , m,表示障碍个数和土球的稳定性
接下来一行两个整数,分别表示障碍的ai和bi 

输出描述 

若可以,输出“Yes”(不含引号),否则输出“No”(不含引号)

示例1 

1
5 50
49 49
52 0
5 10
26 24
70 70

输出 

No

备注:Σn <= 500000, 1<=m<=100000,0<=a,b<=100000

思路 

         题目的前提条件是在合理的安排障碍的顺序,因此本题采用贪心算法,先合理规划安排障碍顺序。首先分析题目可以将障碍分为两类:第一类是冲撞后的稳定性大于冲撞前的稳定性(ai<bi),第二类是冲撞后的稳定性小于冲撞前的稳定性(ai>bi)。将第一类的障碍放在第二类前是更加合理的,因为冲撞第一类障碍之后的稳定性是大于冲撞前,若第一类障碍稳定性小于0,则第二类障碍稳定性更小于0。大类分完之后开始分析小类:在第一类中,优先考虑丧失稳定性小的障碍,即对第一类障碍按照ai进行升序排序;在第二类中,优先考虑回馈稳定性大的障碍,即对第二类障碍按照bi进行降序排序。注意:若在冲撞第一类障碍时已经无法维持稳定性,则不用再对第二类障碍进行冲撞,因此使用flag对第一类进行标记。

代码 

第一段代码: 对数据进行存储以及处理。

T = int(input())
for _ in range(T):
    n,m = map(int,input().split())
    a = [] #存最后为增加稳定性的障碍
    b = [] #存最后为减少稳定性的障碍
    flag = 1
    for _ in range(n):
        ai,bi = map(int,input().split())
        if bi - ai > 0:
            a.append((ai,bi,bi - ai))
        else:
            b.append((ai,bi,bi - ai))
    a.sort()
    b.sort(key = lambda x:-x[1])

第二段代码: 将土球稳定性与冲撞障碍丧尸的稳定性(ai)进行比较和更新。

    for x,y,z in a:
        if m - x < 0:
            print('No')
            flag = 0
            break
        else:
            m += z

    if flag:
        for x,y,z in b:
            if m - x < 0:
                print('No')
                break
            else:
                m += z
        else:
            print('Yes')

完整代码如下。

T = int(input())
for _ in range(T):
    n,m = map(int,input().split())
    a = [] #存最后为增加稳定性的障碍
    b = [] #存最后为减少稳定性的障碍
    flag = 1
    for _ in range(n):
        ai,bi = map(int,input().split())
        if bi - ai > 0:
            a.append((ai,bi,bi - ai))
        else:
            b.append((ai,bi,bi - ai))
    a.sort()
    b.sort(key = lambda x:-x[1])

    for x,y,z in a:
        if m - x < 0:
            print('No')
            flag = 0
            break
        else:
            m += z

    if flag:
        for x,y,z in b:
            if m - x < 0:
                print('No')
                break
            else:
                m += z
        else:
            print('Yes')

回顾 

        对于这类题型还是要多分析题目意思,对题目进行全方面的剖析,避免遗漏某些情况导致出现问题。这道题还是比较简单的,所以没啥想法。主要还是希望自己能坚持下去,保持对代码的一个手感。 

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小八i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值