链接:https://ac.nowcoder.com/acm/contest/2272/H
来源:牛客网
「土」巨石滚滚
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
空间限制: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; } /** */