upc 4875 第k大数 二分查找
来源:互联网 发布:u盘在mac上不显示文件 编辑:程序博客网 时间:2024/06/11 10:29
4875: 第k大数
时间限制: 10 Sec 内存限制: 128 MB提交: 74 解决: 22
[提交][状态][讨论版]
题目描述
有两个序列a,b,它们的长度分别为n和m,那么将两个序列中的元素对应相乘后得到的n*m个元素从大到小排列后的第k个元素是什么?
输入
输入的第一行为一个正整数T (T<=10),代表一共有T组测试数据。
每组测试数据的第一行有三个正整数n,m和k(1<=n, m<=100000,1<=k<=n*m),分别代表a序列的长度,b序列的长度,以及所求元素的下标。第二行为n个正整数代表序列a。第三行为m个正整数代表序列b。序列中所有元素的大小满足[1,100000]。
输出
对于每组测试数据,输出一行包含一个整数代表第k大的元素是多少。
样例输入
33 2 31 2 31 22 2 11 11 12 2 41 11 1
样例输出
311
设置两个数组a,b,然后从小到大分别排一下序,
首先思考所求的数一定在a[0]*b[0]--a[n-1]*b[n-1],,设置一个mid等于两端除2,接下来寻找所有的乘出来的数中有多少比mid大的,得出mid是第几大元素,如果mid大于k,说明k在mid右边;否则k在mid左边,
然后在不断二分,直到mid=k为止,在找有多少比mid大的数的时候,设a数组从后往前扫,b数组从前往后扫,如果a[i]*b[j]>=mid,则a[i-1]扫的时候直接从b数组的j开始扫,不用从0,想一下就知道。
#include <iostream>#include <string.h>#include <algorithm>using namespace std;typedef long long ll;ll m,n;ll a[100010];ll b[100010];ll judge(ll mid){ ll sum=0; ll j=0; for (int i=n-1;i>=0;i--) for (;j<=m-1;j++) { if (a[i]*b[j]>=mid) { sum+=(m-j); break; } } return sum;}int main(){ ll t,mid; ll k; ll ans; cin>>t; while (t--) { scanf("%lld%lld%lld",&n,&m,&k); for (int i=0;i<n;i++) scanf("%lld",&a[i]); for (int j=0;j<m;j++) scanf("%lld",&b[j]); sort(a,a+n); sort(b,b+m); ll l=a[0]*b[0]; ll r=a[n-1]*b[m-1]; while (l<=r) { mid=(l+r)/2; int po=judge(mid); if (po>=k) { ans=mid; l=mid+1; } else r=mid-1; } printf("%lld\n",ans); }}
阅读全文
0 0
- upc 4875 第k大数 二分查找
- 中石油4875 第k大数(二分)
- ZCMU 1540 第k大数 (二分)
- 中位数与二分->以至于第k大数与二分
- poj3685(二分查找第k小)
- pku2761区间第k大数-二分+树状数组
- cugb1220 两个数组乘积第k大数--二分--2
- 第K大数-二分原来还可以这样
- ACM第K大数——双二分
- 求第k大数
- 第K大数问题
- 寻找第k大数
- 区间第K大数
- zcmu1540 第k大数
- 区间第K大数
- 求第k大数
- 第K大数问题
- 找到第K大数
- 习题6.14
- 当了三年程序员,一朝醒悟!(转)
- Flume开发问题记录
- N个数划分两组,差最小
- 《阿里巴巴Java工作手册》学习笔记
- upc 4875 第k大数 二分查找
- Extjs grid添加多选按钮
- 汉诺塔算法
- python霍夫变换圆形检测、cv.CV_HOUGH_GRADIENT没有定义的解决方法
- Extjs 中Tabpanel使用以及tab切换事件
- Django的login和authenticate模块的使用
- Git flow的使用
- 简单的网站服务器
- JAVA之经典算法二