第k小数据
给定两个整型数组A和B(未排序)。我们将A和B中的元素两两相加可以得到数组C。
譬如A为[1,2],B为[3,4].那么由A和B中的元素两两相加得到的数组C为[4,5,5,6]。
现在给你数组A和B,求由A和B两两相加得到的数组C中,第K小的数字。
输入格式输入可能包含多个测试案例。
对于每个测试案例,输入的第一行为三个整数m,n, k(1<=m,n<=100000, 1<= k <= n *m):n,m代表将要输入数组A和B的长度。
紧接着两行, 分别有m和n个数, 代表数组A和B中的元素。数组元素范围为[0,1e8]。
输出格式对应每个测试案例,
输出由A和B中元素两两相加得到的数组c中第K小的数字。
样例输入
2 2 3
1 2
3 4
3 3 4
1 2 7
3 4 5
样例输出
5
6
#include <stdio.h> #include <iostream> #include <algorithm> #include <math.h> #include <string.h> using namespace std; int a[100002]; int b[100002]; int n,m,k; int cal(int v) { int l,r,mid,i,d=0; int min,max; for(i=1;i<=n;i++) { min=a[i]+b[1]; max=a[i]+b[m]; if(v<min) break; if(v>=max) { d+=m; continue; } l=1,r=m; while(l<=r) { mid=(l+r)/2; if(v<(a[i]+b[mid])) r=mid-1; else l=mid+1; } if(v!=(a[i]+b[l])) l--; d += l; } return d; } int find(int l,int r,int k) { int mid,i; while(l<=r) { mid=(l+r)/2; if(k<=cal(mid)) r=mid-1; else l=mid+1; } return l; } int main() { int i,j,l,r; while(scanf("%d %d %d",&n,&m,&k)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<=m;i++) scanf("%d",&b[i]); sort(&a[1],&a[n+1]); sort(&b[1],&b[m+1]); l=a[1]+b[1]; r=a[n]+b[m]; printf("%d\n",find(l,r,k)); } return 0; }