Moo University - Financial Aid
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 16581 | Accepted: 4909 |
Description
Bessie noted that although humans have many universities they can attend, cows have none. To remedy this problem, she and her fellow cows formed a new university called The University of Wisconsin-Farmside,"Moo U" for short.
Not wishing to admit dumber-than-average cows, the founders created an incredibly precise admission exam called the Cow Scholastic Aptitude Test (CSAT) that yields scores in the range 1..2,000,000,000.
Moo U is very expensive to attend; not all calves can afford it.In fact, most calves need some sort of financial aid (0 <= aid <=100,000). The government does not provide scholarships to calves,so all the money must come from the university's limited fund (whose total money is F, 0 <= F <= 2,000,000,000).
Worse still, Moo U only has classrooms for an odd number N (1 <= N <= 19,999) of the C (N <= C <= 100,000) calves who have applied.Bessie wants to admit exactly N calves in order to maximize educational opportunity. She still wants the median CSAT score of the admitted calves to be as high as possible.
Recall that the median of a set of integers whose size is odd is the middle value when they are sorted. For example, the median of the set {3, 8, 9, 7, 5} is 7, as there are exactly two values above 7 and exactly two values below it.
Given the score and required financial aid for each calf that applies, the total number of calves to accept, and the total amount of money Bessie has for financial aid, determine the maximum median score Bessie can obtain by carefully admitting an optimal set of calves.
Input
* Line 1: Three space-separated integers N, C, and F
* Lines 2..C+1: Two space-separated integers per line. The first is the calf's CSAT score; the second integer is the required amount of financial aid the calf needs
Output
* Line 1: A single integer, the maximum median score that Bessie can achieve. If there is insufficient money to admit N calves,output -1.
Sample Input
3 5 70
30 25
50 21
20 20
5 18
35 30
Sample Output
35
Hint
Sample output:If Bessie accepts the calves with CSAT scores of 5, 35, and 50, the median is 35. The total financial aid required is 18 + 30 + 21 = 69 <= 70.
描述
贝西指出,虽然人类有很多可以上的大学,但奶牛却没有。为了解决这个问题,她和她的奶牛同胞们组建了一所新大学,名为威斯康星大学法姆赛德分校,简称“Moo U”。
由于不想招收比普通奶牛更笨的奶牛,创始人创建了一项极其精确的入学考试,称为奶牛学术能力倾向测试 (CSAT),其得分范围为 1..2,000,000,000。
Moo U 的学费非常昂贵;并非所有的小牛都能负担得起。事实上,大多数小牛都需要某种经济援助(0<=援助<=100,000)。政府不给小牛提供奖学金,所以所有的钱都必须来自大学的有限基金(总金额为F,0 <= F <= 2,000,000,000)。
更糟糕的是,Moo U 的教室只能容纳 C(N <= C <= 100,000)个已申请的小牛中的奇数 N(1 <= N <= 19,999)个小牛。Bessie 想要接纳 N 个小牛,以便最大限度地利用教育机会。她仍然希望被录取的犊牛的 CSAT 分数中位数尽可能高。
回想一下,一组大小为奇数的整数的中位数是它们排序后的中间值。例如,集合 {3, 8, 9, 7, 5} 的中位数是 7,因为恰好有两个值高于 7,也恰好有两个值低于 7。
给定适用的每头小牛的分数和所需的经济援助、要接受的小牛总数以及贝西用于经济援助的总金额,确定贝西通过仔细接纳一组最佳小牛可以获得的最大中位数分数。
输入
* 第 1 行:三个空格分隔的整数 N、C 和 F
* 第 2..C+1 行:每行两个空格分隔的整数。首先是小牛的CSAT成绩;第二个整数是小牛需要的经济援助金额
输出
* 第 1 行:单个整数,Bessie 可以获得的最大中位数分数。如果没有足够的钱来接纳N头小牛,则输出-1。
输入样本
3 5 70
30 25
50 21
20 20
5 18
35 30
样本输出
35
暗示
示例输出:如果 Bessie 接受 CSAT 分数为 5、35 和 50 的小牛,则中位数为 35。所需的经济援助总额为 18 + 30 + 21 = 69 <= 70。
£在可选的方案中(从第N个方案开始),每次选择(N-1)/2个花费资金最小且比当前中位数小的数及每次选择(N+1)/2个分数最高的数。
——最小的资金花费意味着可选的更大资金花费的数不比其他方案少,而更大资金花费的数可能存在着更大的分数。因此在保持(N+1)/2个分数最大的数,(N-1)/2个花费资金最小的数的情况下,该方案选取的中位数不会比其他方案小。
创建三个堆。一个资金最小堆。一个分数最小堆,一个资金最大堆。
将原始数据放入资金最小堆。通过遍历该堆,不断维护分数最小堆和资金最大堆,符合资金援助的就更新中位数,最终能找到一个符合资金援助的最大的中位数分数。
具体代码如下:
#include<iostream>
#include<queue>
using namespace std;
#define MAX_N 100005
struct tmp1
{
int CSAT;
int Fund;
friend bool operator<(tmp1 t1,tmp1 t2)
{
return t1.CSAT>t2.CSAT; //分数最小堆
}
};
struct tmp2
{
bool operator() (tmp1 t1,tmp1 t2)
{
return t1.Fund<t2.Fund; //资金最大堆
}
};
struct tmp3
{
bool operator() (tmp1 t1,tmp1 t2)
{
return t1.Fund>t2.Fund; //资金最小堆
}
};
priority_queue<tmp1> q3; //分数最小
priority_queue<tmp1, vector<tmp1>, tmp2> q2; //资金最大
priority_queue<tmp1, vector<tmp1>, tmp3> q1; //资金最小
int N,C,F;
int Money=0;
int ans=-1;
void solve()
{
for(int i=0;i<N;++i)
{
q3.push(q1.top());
Money+=q1.top().Fund;
q1.pop();
}
for(int i=0;i<(N-1)/2;++i)
{
q2.push(q3.top());
q3.pop();
}
if(Money<=F)
ans=q3.top().CSAT;
else
{
printf("-1\n");
return;
}
while(!q1.empty())
{
tmp1 t1=q1.top(),t3=q3.top();
if(t1.CSAT>t3.CSAT)
{
q3.push(t1);
Money+=t1.Fund;
q2.push(t3);
q3.pop();
Money-=q2.top().Fund;
q2.pop();
}
q1.pop();
if(Money<=F)
ans=q3.top().CSAT;
}
printf("%d\n",ans);
}
int main()
{
scanf("%d%d%d",&N,&C,&F);
for(int i=0;i<C;++i)
{
tmp1 t;
scanf("%d%d",&t.CSAT,&t.Fund);
q1.push(t);
}
solve();
return 0;
}