题目描述:

给定两个整型数组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 此题真的很难。这个题的难度在于数组的长度非常长长长长长长长长长长长长长长长长长长长长,我开始的代码是这样的:
 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#define MAX 100009 long long A[MAX];
long long B[MAX];
long long C[MAX]; int cmp(const void *a, const void *b) {
long long at = *(long long *)a;
long long bt = *(long long *)b;
return (int)(at - bt);
} int main(int argc, char const *argv[])
{
int m, n, k;
while(scanf("%d %d %d",&m, &n, &k) != EOF) {
for(int i = ; i < m; i++) {
scanf("%lld",&A[i]);
}
for(int i = ; i < n; i++) {
scanf("%lld",&B[i]);
}
int t = ;
for(int i = ; i < m; i++) {
for(int j = ; j < n; j++) {
C[t] = A[i] + B[j];
t++;
}
} qsort(C, t, sizeof(long long), cmp);
printf("%lld\n", C[k-]);
}
return ;
}

结果就run time error了

之后才明白此题需要用二分搜索,现对A,B两个数组排序,可知道他们的最大值,最小值。那么所要求的第几小的数字必然在这两个值之间,我们此时采用二分搜索的办法去找到这个值。具体的做法是先求出中间值mid,在求出中间值mid在序列中是第几小的数字,从而改变max值和min值,再不断的求下去。但一开始还是超时了,

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#define MAX 100009 long long A[MAX];
long long B[MAX]; int cmp(const void *a, const void *b) {
long long at = *(long long *)a;
long long bt = *(long long *)b;
return (int)(at - bt);
} long long findbit(long long mid, long long n, long long m) {
int ans = n*m;
for(long long int i = ; i < n; i++) {
for(long long int j = m -; j >= ; j--) {
if(A[i] + B[j] > mid) {
ans--;
}
else {
break;
}
}
}
return ans;
} int main(int argc, char const *argv[])
{
long long int m, n, k;
//freopen("input.txt","r",stdin);
while(scanf("%lld %lld %lld",&m, &n, &k) != EOF) {
for(int i = ; i < m; i++) {
scanf("%lld",&A[i]);
}
for(int i = ; i < n; i++) {
scanf("%lld",&B[i]);
} qsort(A, n, sizeof(long long),cmp);
qsort(B, m, sizeof(long long),cmp); long long max = A[n - ] + B[m - ];
long long min = A[] + B[];
long long mid; while(min <= max) {
mid = (max + min)/;
long long midBit = findbit(mid, n, m);
if(k <= midBit) {
max = mid - ;
}
else {
min = mid + ;
}
} printf("%lld\n",min);
}
return ;
}

超时的原因在于findBit内的二层循环。我们如果将第一个数组从小到大遍历,而将第二个数组从大到小遍历,比如下面

6 9 11

8 11 13

如果a[0] + b[1] > 15, (6 +11 > 15),那么a[1] + b[1] 必然也大于15,因为a[1] > a[0], a[1] + b[2]也必然大于15,因为b[2] > b[1]

所以需要遍历每一个a,而对于b只需要进行局部的遍历。

也就是说,对于a[0]生成的序列,mid是第mid0 = j+1小的数字,那么对于a[1], j只需要从上一个j开始算起,因为前面的肯定比mid要大。

代码如下

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#define MAX 100009 long long A[MAX];
long long B[MAX]; int cmp(const void *a, const void *b) {
long long at = *(long long *)a;
long long bt = *(long long *)b;
return (int)(at - bt);
} long long findbit(long long mid, long long n, long long m) {
long long int ans = ; long long int j = m - ;
for(long long int i = ; i < n; i++) {
while(j >= && A[i] + B[j] > mid) {
j--;
}
ans = ans + j + ;
}
return ans;
} int main(int argc, char const *argv[])
{
long long int m, n, k;
//freopen("input.txt","r",stdin);
while(scanf("%lld %lld %lld",&m, &n, &k) != EOF) {
for(int i = ; i < m; i++) {
scanf("%lld",&A[i]);
}
for(int i = ; i < n; i++) {
scanf("%lld",&B[i]);
} qsort(A, n, sizeof(long long),cmp);
qsort(B, m, sizeof(long long),cmp); long long max = A[n - ] + B[m - ];
long long min = A[] + B[];
long long mid; while(min <= max) {
mid = (max + min)/;
long long midBit = findbit(mid, n, m);
if(k <= midBit) {
max = mid - ;
}
else {
min = mid + ;
}
} printf("%lld\n",min);
}
return ;
}

九度oj 题目1534:数组中第K小的数字的更多相关文章

  1. 九度OJ 1534 数组中第K小的数字 -- 二分查找

    题目地址:http://ac.jobdu.com/problem.php?pid=1534 题目描述: 给定两个整型数组A和B.我们将A和B中的元素两两相加可以得到数组C. 譬如A为[1,2],B为[ ...

  2. 数组中第K小的数字(Google面试题)

    http://ac.jobdu.com/problem.php?pid=1534 题目1534:数组中第K小的数字 时间限制:2 秒 内存限制:128 兆 特殊判题:否 提交:1120 解决:208 ...

  3. 九度OJ 题目1534:数组中第K小的数字(二分解)

    题目链接:点击打开链接 题目描述: 给定两个整型数组A和B.我们将A和B中的元素两两相加可以得到数组C. 譬如A为[1,2],B为[3,4].那么由A和B中的元素两两相加得到的数组C为[4,5,5,6 ...

  4. 九度 1534:数组中第K小的数字(二分法变形)

    题目描述: 给定两个整型数组A和B.我们将A和B中的元素两两相加可以得到数组C.譬如A为[1,2],B为[3,4].那么由A和B中的元素两两相加得到的数组C为[4,5,5,6].现在给你数组A和B,求 ...

  5. 题目1534:数组中第K小的数字 ——二分

    http://ac.jobdu.com/problem.php?pid=1534 给定两个整型数组A和B.我们将A和B中的元素两两相加可以得到数组C.譬如A为[1,2],B为[3,4].那么由A和B中 ...

  6. 九度OJ 1351:数组中只出现一次的数字 (位运算)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3098 解决:906 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 每个 ...

  7. 九度OJ 1348:数组中的逆序对 (排序、归并排序)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2777 解决:656 题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组 ...

  8. 九度OJ 题目1371:最小的K个数

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 输入: 每个测试案例包括2行: 第一行为2个整数n,k(1< ...

  9. 九度OJ 题目1384:二维数组中的查找

    /********************************* * 日期:2013-10-11 * 作者:SJF0115 * 题号: 九度OJ 题目1384:二维数组中的查找 * 来源:http ...

随机推荐

  1. 2017“编程之美”终章:AI之战勇者为王

    编者按:8月15日,第六届微软“编程之美”挑战赛在选手的火热比拼中圆满落下帷幕.“编程之美”挑战赛是由微软主办,面向高校学生开展的大型编程比赛.自2012年起,微软每年都在革新比赛命题.紧跟时代潮流, ...

  2. org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'userId' not found. Available parameters are [arg1, arg0, param1, param2]

    2018-06-27 16:43:45.552  INFO 16932 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : ...

  3. spark 之主成分分析

    C4∗2

  4. 带二级目录的Nginx配置------目前找到的最简单的方法

    由于项目不知一个,所以不得不为每一个项目建一个专有的文件夹,这就导致了在配置nginx的时候会出现二级目录 目前找到的最简单的方法     - step1:修改 vue.config.js   添加配 ...

  5. v-if与v-show的区别与选择

      v-if与v-show的区别与选择 官网给的区别 v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建. v-if也是惰性的:如果在初始渲染时条件 ...

  6. webStorm Ctrl+s 自动格式化 然后 保存 用宏命令

    使用WebStorm的Macros宏指令,实现保存的同时格式化代码,并跳至行尾 https://blog.csdn.net/gyz718/article/details/70556188

  7. flume启动报错

    执行flume-ng agent -c conf -f conf/load_balancer_server.conf -n a1 -Dflume.root.logger=DEBUG,console , ...

  8. GloVe:另一种Word Embedding方法

    若想深层地理解GloVe和本文,最好了解SVD, word2vec(skip-gram为主)的相关知识.若仅寻求一种新的word embedding方法,可以不必了解以上前置知识. 一言以蔽之,Glo ...

  9. 分享一个C++与Python开发的中小型通用游戏服务端框架(跨平台,开源,适合MMORPG游戏)

    在开发一款游戏项目时,在立项时我们往往会考虑或者纠结很多,比如: 1,对于开发来说:服务端和客户端应该选择什么语言?用什么协议通信才更效率?协议后期如何维护?Socket是用长连接还是短连接?TCP还 ...

  10. HDU-1217-Arbitrage(SPFA)

    这题和以往的求最短路的题目略微有点不一样,以往求的都是最小的,这题求的是大的,而且还是乘法. 我们求的时候初始化的时候就要进行相反的初始化了,把它们初始化为0,然后比较大的就更新. 因为这题的点少边多 ...