题目地址:http://ac.jobdu.com/problem.php?pid=1534
- 题目描述:
-
给定两个整型数组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,1e9]。
- 输出:
-
对应每个测试案例,
输出由A和B中元素两两相加得到的数组c中第K小的数字。
- 样例输入:
-
2 2 3 1 2 3 4 3 3 4 1 2 7 3 4 5
- 样例输出:
-
5 6
- 来源:
- Google面试题
#include <stdio.h> #include <stdlib.h> int compare(const void * p, const void * q){ return *(long long *)p - *(long long *)q; } long long cal (long long A[], long long m, long long B[], long long n, long long mid){ long long i, j; long long cnt = 0; j = n - 1; for (i=0; i<m; ++i){ while (j>=0 && A[i]+B[j]>mid) --j; cnt += (j + 1); } return cnt; } long long findKth (long long A[], long long m, long long B[], long long n, long long k){ long long min = A[0] + B[0]; long long max = A[m - 1] + B[n - 1]; long long mid; long long ans; while (min <= max){ mid = ((max - min) >> 1) + min; if (k <= cal (A, m, B, n, mid)){ max = mid - 1; } else min = mid + 1; } return min; } int main(void){ long long m, n; long long k; long long A[100000], B[100000]; long long i; while (scanf ("%lld%lld%lld", &m, &n, &k) != EOF){ for (i=0; i<m; ++i) scanf ("%lld", &A[i]); for (i=0; i<n; ++i) scanf ("%lld", &B[i]); qsort (A, m, sizeof(long long), compare); qsort (B, n, sizeof(long long), compare); printf ("%lld ", findKth (A, m, B, n, k)); } return 0; }
参考资料:http://www.cnblogs.com/huhuuu/p/3320416.html