Sunscreen(算法竞赛进阶指南-贪心+优先队列)

18 篇文章 0 订阅

原题链接Sunscreen

题目大意:

 题目本身不好理解,大致题意是:有C头牛L瓶防晒霜,每一头牛有一个区间,一头牛可以涂一瓶防晒霜,如果可以涂在这头牛的区间内,是好的.(一瓶防晒可以涂多个牛),答案尽可能大.

主要思路:

万能的排序。。。。

牛:按照牛的左区间从小到大排序,如果左区间一样则按照右区间从小到大排序

防晒霜:按照防晒值按照从小到大排序

优先队列:定义从小到大

排好后按顺序遍历每一个防晒霜,和牛,如果当前防晒霜的值小于牛的左端点(说明可能是答案),将牛的右端点放入队列(将所有牛左端点小于当前遍历的防晒霜的值的所有牛的右端点放入队列)

每次取出队顶值(当前队列最小值)判断是否大于防晒霜的值(判断防晒霜是否在牛的区间内)

为什么取最小?

牛的区间越小对防晒的要求越苛刻,故优先判断右区间的最小值。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e4;
struct PW1{
	int s1,s2;		
}a[N];
struct PW2{
	int s1,s2;
}b[N];
bool cmp1(PW1 c,PW1 d){
	if(c.s1!=d.s1) return c.s1<d.s1;
	else return c.s2<d.s2;
}
bool cmp2(PW2 c,PW2 d){
	return c.s1<d.s1;
}
int main(){
	int n,m; scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&a[i].s1,&a[i].s2);
	} 
	for(int i=1;i<=m;i++){
		scanf("%d%d",&b[i].s1,&b[i].s2);
	}
	priority_queue<int, vector<int>, greater<int> > p;
	sort(a+1,a+1+n,cmp1);
	sort(b+1,b+1+m,cmp2);
	int j=1,ans=0;
	for(int i=1;i<=m;i++){
		while(j<=n&&a[j].s1<=b[i].s1){
			p.push(a[j].s2);
			j++;
		}
		while(b[i].s2&&!p.empty()){
			int x=p.top();
			p.pop();
			if(x<b[i].s1) continue;
			ans++;
			b[i].s2--;
		}
	}
	printf("%d",ans);
	return 0;
} 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

要用bug来打败bug

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

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

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

打赏作者

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

抵扣说明:

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

余额充值