→題目鏈接←
【想說的話】
期中考試gg了...
寫發水題壓壓驚
【題解】
用兩個數組,一個按分數從小到大排序,一個按價格從小到大排序
在按分數排序的數組上進行二分,把它當作中位數,然後在另一個數組中掃一遍找到兩邊的數,判斷是否合法
複雜度O(nlogn)
[2018-10-21]:突然發現沒有單調性,所以二分是假的,但是數據太弱了所以過了,還是優先隊列吧...
【代碼】
#include<bits/stdc++.h>
#define MAXN 100010
using namespace std;
inline int rd(){
int x=0,y=1;char c=getchar();
while(c<'0' || c>'9'){if(c=='-')y=-y;c=getchar();}
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x*y;
}
struct node{
int val,cost;
int num;
};
bool cmp1(node a,node b){
return a.val<b.val;
}
bool cmp2(node a,node b){
return a.cost<b.cost;
}
int n,m,k;
node a[MAXN],b[MAXN];
bool check(int x){
if(x-1<n/2 || m-x<n/2)return false;
int sum=a[x].cost,tot1=0,tot2=0;
for(int i=1; i<=m; i++){
if(b[i].num==a[x].num)continue;
if(tot1<n/2 && b[i].val<=a[x].val)tot1++,sum+=b[i].cost;
else if(tot2<n/2 && b[i].val>=a[x].val)tot2++,sum+=b[i].cost;
if(sum>k)return false;
}
if(tot1<n/2 || tot2<n/2)return false;
return true;
}
int main(){
n=rd(),m=rd(),k=rd();
for(int i=1; i<=m; i++){
a[i].val=rd();
a[i].cost=rd();
a[i].num=i;
b[i]=a[i];
}
sort(a+1,a+m+1,cmp1);
sort(b+1,b+m+1,cmp2);
int l=1,r=m;
int ans=-1;
while(l<=r){
int mid=(l+r)/2;
if(check(mid))ans=a[mid].val,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}