Kattis - icpccamp ICPC Camp(二分+贪心)

Posted Frozen_Guardian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kattis - icpccamp ICPC Camp(二分+贪心)相关的知识,希望对你有一定的参考价值。

题目链接:点击查看

题目大意:给出两种种类的数字分别 m 1 m_1 m1 m 2 m_2 m2 个,现在要求匹配 n n n 个不同种类的数字,每个数字只能使用一次,且两数之和不能超过 s s s,输出任意两对数字之差最大值的最小值

题目分析:

首先二分答案将最值问题转换为检验问题。

假如差值确定后,每个数字就会出现一个可匹配的区间,设数字为 x x x,差值为 d d d,则其可以匹配另一种类的数字区间为 [ x − d , min ⁡ ( x + d , s − x ) ] [x-d,\\min(x+d,s-x)] [xd,min(x+d,sx)]

于是转换为了区间和数字的最大匹配问题了:POJ - 3614 Sunscreen

用优先队列可以在 O ( n l o g n ) O(nlogn) O(nlogn) 的复杂度内实现,加上二分,所以本题的复杂度为 O ( n l o g 2 n ) O(nlog^2n) O(nlog2n)

代码:

// Problem: ICPC Camp
// Contest: Virtual Judge - Kattis
// URL: https://vjudge.net/problem/Kattis-icpccamp
// Memory Limit: 1048 MB
// Time Limit: 4000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{
	T f=1;x=0;
	char ch=getchar();
	while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	x*=f;
}
template<typename T>
inline void write(T x)
{
	if(x<0){x=~(x-1);putchar('-');}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
struct Node {
	int l,r;
	bool operator<(const Node& t)const {
		return r>t.r;
	}
};
int a[N],b[N],n,m1,m2,s;
bool check(int d) {
	vector<Node>node;
	for(int i=1;i<=m2;i++) {
		int l=b[i]-d,r=min(b[i]+d,s-b[i]);
		node.push_back({l,r});
	}
	sort(node.begin(),node.end(),[&](Node a,Node b) {
		if(a.l!=b.l) {
			return a.l<b.l;
		}
		return a.r<b.r;
	});
	int cnt=0,pos=0;
	priority_queue<Node>q;//右端点大的区间优先级更高
	for(int i=1;i<=m1;i++) {
		while(pos<m2&&node[pos].l<=a[i]) {//将左端点小于等于a[i]的区间都压入优先队列候选
			q.push(node[pos]);
			pos++;
		}
		while(q.size()) {//右端点小于a[i]的区间后面肯定也用不到了,舍弃即可
			int r=q.top().r;
			q.pop();
			if(r>=a[i]) {
				cnt++;
				break;
			}
		}
	}
	return cnt>=n;
}
int main()
{
#ifndef ONLINE_JUDGE
//	freopen("data.in.txt","r",stdin);
//	freopen("data.out.txt","w",stdout);
#endif
//	ios::sync_with_stdio(false);
	read(n),read(m1),read(m2),read(s);
	for(int i=1;i<=m1;i++) {
		read(a[i]);
	}
	for(int i=1;i<=m2;i++) {
		read(b[i]);
	}
	sort(a+1,a+1+m1);
	int l=0,r=inf,ans=-1;
	while(l<=r) {
		int mid=(l+r)>>1;
		if(check(mid)) {
			ans=mid;
			r=mid-1;
		} else {
			l=mid+1;
		}
	}
	cout<<ans<<endl;
	return 0;
}

以上是关于Kattis - icpccamp ICPC Camp(二分+贪心)的主要内容,如果未能解决你的问题,请参考以下文章

Kattis-Association for Computing Machinery

Kattis-Association for Computing Machinery

Kattis-Association for Computing Machinery

2018 ICPC Asia Singapore Regional A. Largest Triangle (计算几何)

HDU 5963 博弈

2019ICPC(沈阳) - Flowers(二分)