Codeforces 1251D Salary Changing

思路:

1.用pair数组存储每个员工的最小和最大工资,然后进行降序排序;
2.记过程中工资中位数为mid,我们选定一个区间二分查找这个mid;如果所有员工都发放最小工资,那么此刻的mid就应该是所有mid的下界,而总工资S则应该是mid的上界;
3.每次选定一个mid后,我们应该判断这个mid合不合适,判断条件是能找到(n+1)/2个人的工资可以达到mid且总工资不会超过S;至于如何选取这个(n+1)/2个人,排序+贪心就好了;

代码:

#define IOS ios::sync_with_stdio(false)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> P;
#define fi first
#define sc second
#define rp(i,n) for(int i=0;i<n;i++)
#define rpn(i,n) for(int i=1;i<=n;i++)
const int MAX_N=2e5+5;
P emp[MAX_N];
int n,num;
LL s;
bool ok(LL mid){
	LL cost=0;
	int ans=0;
	rp(i,n){
		if(emp[i].fi>=mid) ans++;
		else if(emp[i].sc>=mid){
			cost+=mid-emp[i].fi;
			ans++;
		}
		if(cost>s) return false;
		if(ans==num) return true;
	}
	return false;
}
int main(){
	IOS;
	int t;
	cin>>t;
	while(t--){		
		cin>>n>>s;
		num=(n+1)>>1;
		rp(i,n) cin>>emp[i].fi>>emp[i].sc;
		sort(emp,emp+n,greater<P>());
		LL lf=emp[n>>1].fi,rt=s,rs;
		rp(i,n) s-=emp[i].fi;
		while(rt>=lf){
			LL mid=(lf+rt)>>1;
			if(ok(mid)){
				lf=mid+1;
				rs=mid;
			}
			else rt=mid-1;
		}
		cout<<rs<<'\n';
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值