1540 第k大数
2017-11-26 22:29
337 查看
1540: 第k大数
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 573 Solved: 73
[Submit][Status][Web
Board]
Description
有两个序列a,b,它们的长度分别为n和m,那么将两个序列中的元素对应相乘后得到的n*m个元素从大到小排列后的第k个元素是什么?Input
输入的第一行为一个正整数T (T<=10),代表一共有T组测试数据。每组测试数据的第一行有三个正整数n,m和k(1<=n, m<=100000,1<=k<=n*m),分别代表a序列的长度,b序列的长度,以及所求元素的下标。第二行为n个正整数代表序列a。第三行为m个正整数代表序列b。序列中所有元素的大小满足[1,100000]。
Output
对于每组测试数据,输出一行包含一个整数代表第k大的元素是多少。Sample Input
33 2 31 2 31 22 2 11 11 12 2 41 11 1Sample Output
311HINT
Source
首届全国中医药院校大学生程序设计竞赛[Submit][Status][Web
Board]
具体解析,看下代码
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
#define ll long long
using namespace std;
const int maxn=1000000+5;
ll a[maxn],b[maxn];
ll t,n,m,k;
bool cmp(int A,int B){
return A > B;
}
ll jdg(ll mid){
ll cnt=0;
ll j=1;
for(ll i=n;i>=1;i--){
/*
这里也很细节,对a数组从最大的开始,对b数组从最小的开始,如果a*b里面某个比较小的了,
那么a[i]后面的那个题,肯定乘以比当前b[j]大的数,然后就优化出来了。
*/
while(j <=m){
if(a[i]*b[j] >= mid){
cnt+=m-j+1;
break ;
}
else{
j++;
}
}
}
return cnt;
}
int main(){
scanf("%lld",&t);
while(t--){
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int j=1;j<=m;j++) scanf("%lld",&b[j]);
sort(a+1,a+1+n);
sort(b+1,b+1+m);
ll mid,left,right;
left=a[1]*b[1];/*最小值*/
right=a
*b[m];/*最大值*/
ll ans;
while(left <= right){
mid=(left+right)/2;
/*这里可以是一点点逼近吧*/
ll ce=jdg(mid);
if(ce >= k){
ans=mid;
left=mid+1;
}
else{
right=mid-1;
}
}
printf("%lld\n",ans);
}
return 0;
}
相关文章推荐
- zcmu1540 第k大数
- 1540: 第k大数 两个数组元素相乘后的第k大( 二分答案 + 输入输出优化 )
- ZCMU-1540-第K大个数
- ZCMU 1540 第k大数 (二分)
- zcmu 1540: 第k大数
- 第十三题(输出该链表中倒数第k 个结点)
- hdu 2639 第k最大值
- poj1716(treap树求区间第k小的数字)
- POJ2449Remmarguts' Date(A*算法求第K小路)
- 2014年美团校招之——输出字典序为第k的排列(0<=k<n!)
- 设有一个N组数,要确定第K大的数
- hdu 1540 Tunnel Warfare(线段树)
- 17082 两个有序数序列中找第k小(递归)
- POJ 2449 Remmarguts' Date 第K短路 A*
- 关于利用快排思想求第K小数的分析
- 分治算法求N个数中第K小(大)的数
- 2015 年 JXNU_ACS 算法组寒假第一次周赛 1003 第K小的数
- poj 2449 (第K短路) A* + dij
- 【POJ2761】【区间第k大】Feed the dogs(吐槽)
- hdu-1540(线段树+最大连续区间)