第K大的数 题解
题面
题目描述
数组A和数组B,里面都有n个整数。
数组C共有n^2个整数,分别是:
是数组A同数组B的组合,求数组C中第K大的数。
例如:
与 组合成的 为
B[0] | B[1] | B[2] | |
---|---|---|---|
A[0] | 2 | 4 | 6 |
A[1] | 3 | 6 | 9 |
A[2] | 4 | 8 | 12 |
共 个数。
输入
第1行:2个数N和K,中间用空格分隔。N为数组的长度,K对应第K大的数。( )
第2 - N + 1行:每行2个数,分别是 和 。( )
输出
输出第K大的数。
样例输入
3 2
1 2
2 3
3 4
样例输出
9
解析
不难想到暴力做法,枚举所有的结果,时间复杂度 空间复杂度 明显TLE+MLE。
我们发现,答案满足单调性,我们二分答案。
那么 check(x)
就是查找 中比 大的数字个数。
然后考虑 check(x)
函数的设计,一个一个枚举也可以,但是,我们发现,对于每个 ,我们又可以进行一次二分查找来找到比 大的值中最小的一个,然后进行计算得到结果。
代码:
#include<cstdio> #include<algorithm> #define maxn 50039 using namespace std; typedef long long ll; typedef long long Type; inline Type read(){ Type sum=0; int flag=0; char c=getchar(); while((c<'0'||c>'9')&&c!='-') c=getchar(); if(c=='-') c=getchar(),flag=1; while('0'<=c&&c<='9'){ sum=(sum<<1)+(sum<<3)+(c^48); c=getchar(); } if(flag) return -sum; return sum; } ll a[maxn],b[maxn]; int n,k; int find(ll x){ int sum=0; int left,right,middle; for(int i=1;i<=n;i++){ left=0,right=n+1; while(left+1<right){ middle=(left+right)>>1; if(a[i]*b[middle]>=x) left=middle; else right=middle; } sum+=left; } //printf("%lld %d\n",x,sum); return sum; } int cmp(ll xx,ll yy){ return xx>yy; } ll l,r,mid; int main(){ n=read(); k=read(); for(int i=1;i<=n;i++){ a[i]=read(); b[i]=read(); } sort(a+1,a+n+1,cmp); sort(b+1,b+n+1,cmp); l=0,r=a[1]*b[1]+1; while(l+1<r){ mid=(l+r)/2; if(find(mid)>=k) l=mid; else r=mid; } printf("%lld",l); return 0; }
提示
如果你没有AC,注意一下几点:
- 除法带来的精度问题
- 十年OI一场空,不开
long long
见祖宗
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具