D
1.题意:
有C个奶牛去晒太阳(1 <=C <= 2500),每个奶牛各自能够忍受的阳光强度有一个最小值和一个最大值,太大就晒伤了,太小奶牛没感觉。
奶牛涂防晒霜问题,先输入奶牛数C、防晒霜种类L,再输入C头奶牛的防晒指数范围minSPF -- maxSPF,再输入L中防晒霜的防晒指数SPF和瓶数cover。求最多有几头牛可以涂防晒霜。
2.算法思路:
(1)那么将奶牛按照阳光强度的最小值从小到大排序。用结构体储存
将防晒霜也按照能固定的阳光强度从小到大排序。用结构体储存
(2)这里用到了优先队列思想。
从最小的防晒霜枚举,将所有符合 最小值小于等于该防晒霜的 奶牛的 最大值 放入优先队列之中。然后优先队列是小值先出,所以就可以将这些最大值中的最小的取出来。更新答案。
priority_queue<int, vector<int>, greater<int> > q; //优先队列,greater从小到大排列,top为最小的元素;(这里拓展less是:从大到小排列)
3.代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <vector>
#include <queue>
#define Max 2555
using namespace std;
int C, L;
priority_queue<int, vector<int>, greater<int> > q; //优先队列,greater从小到大排列,top为最小的元素;(这里拓展less从大到小排列)
struct Cow //定义奶牛防晒等级结构体
{
int minSPF;
int maxSPF;
}cow[Max];
struct Bottle //定义防晒霜等级结构体
{
int SPF; //防晒霜等级
int cover; //可以给几头奶牛用
}bottle[Max];
int cowAsc(Cow a , Cow b) //奶牛升序函数
{
return a.minSPF < b.minSPF;
}
int botAsc(Bottle a , Bottle b) //防晒霜升序函数
{
return a.SPF < b.SPF;
}
int MaxCNum()
{
int count=0;
int i,j=0; //j忘了赋值
for(i=0;i<L;i++) //i忘了改
{
while(j < C && cow[j].minSPF <= bottle[i].SPF) //将符合防晒霜i的奶牛的maxSPF,进队
{
q.push(cow[j].maxSPF); //每次j不清零,从上次循环的j累计,这样保证遍历一次奶牛样本
j++;
}
while(!q.empty() && bottle[i].cover) //当队列非空,而且防晒霜i有剩余
{
int x = q.top(); //将队头元素出队,即maxSPF最大
q.pop();
if(x < bottle[i].SPF) continue; //如果maxSPF<SPF,则不作下面操作。跳出此次循环,进入下次循环,即判断下一种防晒霜(前面一步已经将其出队)
count++;
bottle[i].cover--; //忘了写--,哎!!!!!!
}
}
return count;
}
int main()
{
int i,count;
scanf("%d %d",&C,&L);
for(i=0 ; i<C ; i++)
{
scanf("%d %d",&cow[i].minSPF,&cow[i].maxSPF);
}
for(i=0 ; i<L ; i++) //L写成了C,都是粘贴复试惹的祸
{
scanf("%d %d",&bottle[i].SPF,&bottle[i].cover);
}
sort(cow,cow+C,cowAsc); //调用排序函数,将奶牛从小到大按照minSPF排列
sort(bottle,bottle+L,botAsc); //调用排序函数,将防晒霜从小到大按照SPF排列
count=MaxCNum();
printf("%d \n",count); // maximum number of cows that can protect themselves
return 0;
}