链接:https://ac.nowcoder.com/acm/contest/2272/H
来源:牛客网

「土」巨石滚滚
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

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

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

土球有一个稳定性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
思路:作者:_tqr
链接:https://ac.nowcoder.com/discuss/346888
来源:牛客网

思路:

很显然的贪心

如果土球碰到障碍不会碎的话,那么尽量先选取 回复-消耗 更大的障碍

如果可以回血,那么优先选择消耗最小的;

如果回血小于了消耗,那么先选择回血最多的

在上述操作过程中,一旦遇到无法选取的,就可以判断无法满足条件了

排序可以只排序一部分啊!!!以前怎么没这么想!!!

看代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=5e5+5;
const int maxm=100000+10;
struct Node
{
    LL a,b,c;
}a[maxn];
bool cmp1(const Node x,const Node y)
{
    return x.c>y.c;
}
bool cmp2(const Node x,const Node y)
{
    return x.a<y.a;
}
bool cmp3(const Node x,const Node y)
{
    return x.b>y.b;
}
int main()
{
    LL T,N,M,sum;scanf("%lld",&T);
    while(T--)
    {
        sum=0;
        scanf("%lld%lld",&N,&M);
        for(int i=0;i<N;i++)
        {
            scanf("%lld%lld",&a[i].a,&a[i].b);
            a[i].c=a[i].b-a[i].a;
            if(a[i].c>0) sum++;
        }
//        if(sum==N) {printf("Yes\n");continue;}
        sort(a,a+N,cmp1);
        //排序之后前sum个都是回血之后稳定性增加的
        //此时贪心前sum个损失小的 从小往大
        sort(a,a+sum,cmp2);
        //剩下的N-sum个全都是回血之后稳定性减少的 但是我们必须必全部的障碍剔除 所以优先选择回血大的
        sort(a+sum,a+N,cmp3);
        int flag=0;
        for(int i=0;i<N;i++)
        {
            if(M<a[i].a)
            {
                flag=1;break;
            }
            M+=a[i].c;
        }
        if(flag==1) printf("No\n");
        else printf("Yes\n");
    }
    return 0;
}
/**

*/
01-12 23:25