题目大意:
有c头牛,选择n头上大学,c头牛分别对应自己的成绩si和需要的补贴fi,但我们拿不出太多钱,最多只有F元资金,所以我们想让生源尽可能中位数成绩尽量高,且需求的补助和不超过F;
解题思路:
有说用二分写的,我不是很推荐这种写法,我是使用的优先队列;
我们既然想得到中位数尽量高,枚举中位数是必不可少的,但是本题数据量不小。枚举是要有技巧的
我们既然要中位数,那么也就是说 前N/2+自己+后N/2的补助不超过F,
因此我们可以用优先队列处理出min_l和min_r,再从【n/2, c - 1- n/2]从后往前枚举,遇到第一个和小于等于F的数即答案。因为此时的中位数最大。
AC代码:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define maxn 1010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(x,y) memset(x,y,sizeof(x))
#define rep(i,n) for(int i=0;i<(n);i++)
#define repf(i,a,b) for(int i=(a);i<=(b);i++)
#define pii pair<int,int>
//#define mp make_pair
#define FI first
#define SE second
#define IT iterator
#define PB push_back
#define Times 10
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int ,int > P;
const double eps = 1e-10;
const double pi = acos(-1.0);
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const ll INF = (ll)1e18+300;
const int maxd = 105050 + 10;
ll c, n, f;
struct node{
ll s, f;
};
node ac[maxd];
ll min_l[maxd];
ll min_r[maxd];
bool cmp(node a, node b) {
return a.s < b.s;
}
bool judge(int id){
if(min_l[id] + min_r[id] + ac[id].f <= f) {
return true;
}return false;
}
void solve(){
priority_queue<ll > que;
ll s = 0;
for (int i = 0; i < c; i++) {
if(i < n/2) {
s += ac[i].f;
que.push(ac[i].f);
}
else {
min_l[i] = s;
if(ac[i].f <= que.top()) {
s -= que.top();
que.pop();
s += ac[i].f;
que.push(ac[i].f);
}
}
}
s = 0;
while(!que.empty()) {
que.pop();
}
for (int i = c-1; i >= 0; i--) {
if(i > c-1- n/2) {
s += ac[i].f;
que.push(ac[i].f);
}
else {
min_r[i] = s;
if(ac[i].f <= que.top()) {
s -= que.top();
que.pop();
s += ac[i].f;
que.push(ac[i].f);
}
}
}
for (int i = c-1-n/2; i >= n/2; i--){
if(judge(i)) {
cout << ac[i].s << endl;
return ;
}
}
cout << "-1" <<endl;
}
int main() {
// ios::sync_with_stdio(false);
cin >> n >> c >> f;
for (int i = 0; i < c; i++) {
scanf("%I64d %I64d", &ac[i].s, &ac[i].f);
//cin >> ac[i].s >> ac[i].f;
}
sort(ac, ac + c, cmp);
solve();
}