educational codeforces Round 75 D(div2)

題目:http://codeforces.com/contest/1251/problem/D
這個枚舉中位數,我們可以排個序,讓工人薪資從大到小排序,然後發現可以用二分去做?(有點像跳石頭的感覺)但這題的難點在於每一個人的薪資都是一個區間,那我們應該怎麼去處理呢(又是一道思維題)?很明顯,薪資總共不能超過k,那我們是不是可以,能取中位數的就取中位數,不能取中位數的就給最少的錢(貪心),這樣就可以既滿足題目要求,又能儘可能滿足薪資小於k了。當然check裏面還要判斷,給大於等於中位數工資的人數有沒有大於等於n/2+1個人(還要滿足中位數的定義嘛)。
代碼還是比較好看的,解釋都可以在文字敘述中找到。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
struct node
{
	int l,r;
}a[200005];
int t,n,s;
long long maxx(int a,int b)
{
	if(a>=b)return a;
	else return b; 
}
bool cmp(node a,node b)
{
	if(a.l==b.l)return a.r>b.r;
	return a.l>b.l;
}
bool check(int zhi)
{
	int flag=n/2+1;
	int sum=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i].r>=zhi&&flag)
		{
			flag--;
			sum+=maxx(a[i].l,zhi);
		}
		else
		{
			sum+=a[i].l;
		}
	}
	return sum<=s&&!flag;
}
signed main()
{
	//freopen("123.txt","w",stdout);
	ios::sync_with_stdio(false);
	cin>>t;
	while(t--)
	{
		cin>>n>>s;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i].l>>a[i].r;
		}
		sort(a+1,a+n+1,cmp);
		int l=1,r=s;
		while(l<r)
		{
			int mid=l+r+1>>1;
			if(check(mid))
			{
				l=mid;
			}
			else
			{
				r=mid-1;
			}
		}
		cout<<l<<endl;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章