「土」巨石滚滚

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

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

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

土球有一个稳定性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

这题还是比较简单的,只是选择何种数据结构来操作。我们知道如果当前的障碍物能够回馈我们更多的稳定性,那么我们选择优先撞它。意思是我们将bi>=ai的放在一起,按照ai,从小到大排序。然后将ai>bi的放在一起,按照ai从大到小排序,如果当前的m小于ai,我们就可以退出了,可以减小一些时间复杂度。
vector容器可以装任意类型的元素,包括结点。然后重载一下排序,然后auto自动类型。记得每一次将vector内容清空。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 5e5+5;
struct node{
	ll a,b;
};
vector<node>adds,subs;
ll n,m;
int cmp1(node a,node b)
{
	return a.a<b.a;
}
int cmp2(node a,node b)
{
	return a.b>b.b;
}
int main()
{
	int tt ; 
	scanf("%d",&tt);
	while(tt--)
	{
		adds.clear();
		subs.clear();
		scanf("%lld %lld",&n,&m);
		for(int i=1; i<=n; i++)
		{
			ll a,b; scanf("%lld %lld",&a,&b);
			if( b>=a ) adds.push_back( {a,b} );
			else subs.push_back( {a,b} );
		}
		sort(adds.begin(),adds.end(),cmp1);
		int flag = 1;
		// 1.首先先撞 a<=b 的障碍物: 先撞a小的,直接模拟 
		for( auto i:adds )
		{
			if( i.a>m ) // 立刻散架 
			{
				flag = 0;
				break;
			}
			else m += (i.b-i.a);
		}
		
		if( flag==0 ) 
		{
			puts("No");
		}
		else
		{
		/*
			2.然后在撞 a>b 
			不管最终排序如何,最终的m值是确定的(如果能完成全部冲撞)。
			倒序来看,即分析逆过程。之前每次冲撞先消耗a,再恢复b,
			逆过程为先增加b后消耗a,所以逆推应当按照b升序排列,
			那么正推就该是按b降序排列。
		*/ 
			sort(subs.begin(),subs.end(),cmp2);
			for( auto i:subs )
			{
				if( i.a>m ) // 立刻散架 
				{
					flag = 0;
					break;
				}
				else m += (i.b-i.a);
			}
			puts(flag?"Yes":"No");
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值