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)] [x−d,min(x+d,s−x)]
于是转换为了区间和数字的最大匹配问题了: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 (计算几何)