[ABC312C] Invisible Hand
题意#
有一些卖家,每个人愿意用大于等于 \(a_i\) 的价格出售苹果。
还有一些买家,每个人愿意用小于等于 \(b_i\) 的价格购买苹果。
现在要求你给定苹果的价格,满足愿意出售的人大于等于愿意购买的人的情况下,苹果的价钱尽量小。
思路#
很显然的一道二分答案,由于我们不需要考虑人选的方案,只需考虑有多少人愿意卖或买,所以可以直接对 \(a\) 数组和 \(b\) 数组进行排序。
而后二分答案,每次用 \(mid\) 在 \(a\) 和 \(b\) 数组中记录出有多少人,由于数组已经排序,所以这个可以使用 lower_bound
和 upper_bound
函数去查找有多少人在苹果价钱为 \(mid\) 的情况下愿意买或卖。
因为当 \(mid\) 越大时,愿意买的人越少,卖的人越多,所以满足单调性,可以二分。
至于为什么要使用 upper_bound
,显然,如果我们在判断有多少人愿意买的时候只是用 lower_bound
,那如果 \(a\) 数组中不含 \(mid\),那么 lower_bound
会查找到大于等于 \(mid\) 的第一个数,其下标设为 \(k\),那么愿意买的人就为 \(k-1\),但如果 \(a\) 含有 \(mid\),则会找到 \(mid\) 本身的下标,最后愿意买的人为 \(k\),所以不妨直接使用 upper_bound
,这样最后愿意买的人数都为 \(k-1\)。
注意 \(1 \le a_i,b_i \le 10^9\),赛时死磕半天没看出来哪错了,结果...是因为 \(r\) 的初始值开小了,开成 \(10^9+100\) 即可,警钟长鸣。
代码#
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
template<typename P>
inline void read(P &x){
P res=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
res=res*10+ch-'0';
ch=getchar();
}
x=res*f;
}
int n,m;
int a[200010];
int b[200010];
bool check(int x){
int sel=upper_bound(a+1,a+n+1,x)-a-1;
int bou=m-(lower_bound(b+1,b+m+1,x)-b)+1;
if(sel>=bou) return 0;
return 1;
}
signed main(){
read(n),read(m);
for(int i=1;i<=n;++i) read(a[i]);
for(int i=1;i<=m;++i) read(b[i]);
sort(a+1,a+n+1);
sort(b+1,b+m+1);
int l=0,r=1e9+100,ans=0;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)) l=mid+1;
else r=mid-1,ans=mid;
};
cout<<ans<<endl;
return 0;
}
作者:God_Max_Me
出处:https://www.cnblogs.com/lizihan00787/p/18323132
版权:本作品采用「God_Max_Me-非商业性使用」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端