POJ3614Sunscreen(优先队列+贪心)

 一共有C个牛,每个牛有一个范围min,max,在这个范围内,能够在阳光下晒,否则被烧烤,同时有L个防晒油,每个防晒油有不同的个数和防晒度,也就是说牛抹了防晒油就有防晒油所定的防晒度了,问一共有多少牛可以不被烧烤

题解中有输入格式

/*贪心策略:
为了尽可能的让更多的牛能够抹上防晒油,那么我就要尽可能用高于他们忍受范围下线尽可能接近的防晒油涂他们,所以,用优先队列排牛的忍受范围下限从低到高,排列防晒油从低到高,然后从选的那些牛里面找忍受范围上限以下的防晒油给他们*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 3000;
pair<int, int> c[maxn];
pair<int, int> s[maxn];
priority_queue<int, vector<int>, greater<int> > pq;     //元素越小,越先出队
int n, m;
int main() {
    /*
    思想:
    先输入的是奶牛能忍受阳光的最小值及最大值;
    接着是防晒霜能固定的阳光强度及数量;
    先将两者分别按奶牛所耐阳光最小值及防晒霜所固定值从小到大排序
    枚举每一个防晒霜,遍历每一个奶牛,看其所耐最小值是否小于等于防晒霜值
    若是,则将其所耐最大值放入队列(第一个while循环实现)接着第二个while循环
    判断队列内奶牛最大值是否大于等于防晒霜固定值;若是,奶牛数加一,此防晒霜数减1
    */
    while(~scanf("%d%d", &n, &m)) {
        for(int i = 0; i < n; i++)
            scanf("%d%d", &c[i].first, &c[i].second);
            //奶牛的忍受最小最大值
        for(int i = 0; i < m; i++)
            //防晒油的耐值和数量
            scanf("%d%d", &s[i].first, &s[i].second);
        sort(c, c+n);
        sort(s, s+m);//从小到大排序;
        int cur = 0;//奶牛的数量
        int ans = 0;
        for(int i = 0; i < m; i++) {//m瓶
            while(cur < n && c[cur].first <= s[i].first) {
                //防晒霜>=奶牛可忍受最小值
                pq.push(c[cur].second);
                //把其最大值放入优先队列
                //这个优先队列自动将里面的数排好序;
                //把奶牛的耐晒最大值放入队列;
                cur++;
            }
            while(!pq.empty() && s[i].second) {
                int x = pq.top(); pq.pop();
                //可能未清除完所有牛,留给下一个防晒霜考虑;
                if(s[i].first <= x) {   //当前这种防晒霜的SPF小于等于当前最大的奶牛maxSPF
                    ans++;
                    //如果防晒值小于忍受阳光的最大值;
                    s[i].second--;
                    //可以使用,其数量减1;
                }
                //否则的话,当前这种防晒霜不能无法涂给之前所有的牛
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值