题意:
给定n个人的可获得的最低工资,和最高工资,和你的总钱数,保证总钱数能满足所有人的最低工资,现在你要用这些钱去分配工资。问这些人最终获得工资的最大中位数。
思路:
二分答案mid,每一次对答案进行判断。
这里又一点贪心的思想,由于想让答案更大,那么尽量就在不影响答案的情况下花更少的钱,所以我们要提升中位数mid,实际上就只需要将(n/2+1)个人的工资提升到mid。每个人都至少要达到最低工资,所以我们尽量让最低工资大的排在前面,这样额外的花费就会更少。由于每个人都有最高工资,所以只需要加一个if判断一下,mid是否超过了此人的最高工资即可。
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
#define ls (i<<1)
#define rs (i<<1|1)
#define fi first
#define se second
#define mk make_pair
#define mem(a,b) memset(a,b,sizeof(a))
LL read()
{
LL x=0,t=1;
char ch;
while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
return x*t;
}
struct node
{
LL l,r;
};
node a[N];
bool cmp(node p,node q)
{
return p.l==q.l?p.r>q.r:p.l>q.l;
}
bool judge(LL x,LL n,LL s)
{
LL res=0;
LL m=(n>>1)+1;
for(int i=1;i<=n;i++)
{
if(a[i].r>=x&&m)
{
res+=max(a[i].l,x);
m--;
}
else res+=a[i].l;
}
return res<=s&&!m;
}
int main()
{
int T=read();
while(T--)
{
LL n=read(),s=read();
for(int i=1;i<=n;i++)
{
a[i].l=read();
a[i].r=read();
}
sort(a+1,a+n+1,cmp);
LL l=1,r=1e16;
while(l<=r)
{
LL mid=(l+r)>>1;
if(judge(mid,n,s)) l=mid+1;
else r=mid-1;
}
printf("%lld
",r);
}
}