时间限制:2 秒

内存限制:32 兆

特殊判题:否

提交:3160

解决:833

题目描述:
输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
输入:
每个测试案例包括两行:
第一行包含一个整数n和k,n表示数组中的元素个数,k表示两数之和。其中1 <= n <= 10^6,k为int
第二行包含n个整数,每个数组均为int类型。
输出:
对应每个测试案例,输出两个数,小的先输出。如果找不到,则输出“-1 -1”
样例输入:
6 15
1 2 4 7 11 15
样例输出:
4 11

思路:

朴素思路是遍历查找,也就是我最初代码中用的方法。复杂度NlogN。

但后来想想,其实根据4xy = (x+y)^2-(x-y)^2,两个数的和一定,那么差越大,积越小,其实只需要找差最大的这一对数即可。可以省掉很多多余的查找。但最坏的复杂度仍然是NlogN。

进一步的优化思路能够将复杂度下降到线性:两个数A和B分别从最左侧和最右侧向中间搜索,每次循环中,固定A,从上次搜索到的B开始下降搜索。最终的复杂度将是N。

PS:这个题的测试数据不是太好,我试了朴素思路和优化思路,结果竟然相差不大。

代码:

#include <stdio.h>

#define N 1000000

int search(int *a, int begin, int end, int x)
{
int len = end - begin;
if (len <= 0)
return -1;
if (len == 1)
{
if (a[begin] == x)
return begin;
else
return -1;
} int mid = begin + len/2;
if (a[mid] == x)
return mid;
else if (x < a[mid])
return search(a, begin, mid, x);
else
return search(a, mid+1, end, x);
} int main(void)
{
int n, k, i, j;
int a[N]; while (scanf("%d%d", &n, &k) != EOF)
{
for(i=0; i<n; i++)
scanf("%d", &a[i]); for (i=0; i<n-1; i++)
{
j = search(a, i+1, n, k-a[i]);
if (j > i)
break;
else
continue;
} if (i == n-1)
printf("-1 -1\n");
else
printf("%d %d\n", a[i], a[j]);
} return 0;
}
/**************************************************************
Problem: 1352
User: liangrx06
Language: C
Result: Accepted
Time:1520 ms
Memory:4748 kb
****************************************************************/

优化代码:

<pre name="code" class="cpp">#include <stdio.h>

#define N 1000000

int main(void)
{
int n, k, i, j;
int a[N]; while (scanf("%d%d", &n, &k) != EOF)
{
for(i=0; i<n; i++)
scanf("%d", &a[i]); i = 0, j = n-1;
while (i < j) {
if (a[i] + a[j] == k)
break;
else if (a[i] + a[j] < k)
i++;
else
j--;
} if (i == j)
printf("-1 -1\n");
else
printf("%d %d\n", a[i], a[j]);
} return 0;
}
/**************************************************************
Problem: 1352
User: liangrx06
Language: C
Result: Accepted
Time:1450 ms
Memory:4748 kb
****************************************************************/

												

九度OJ 1352:和为S的两个数字 (查找)的更多相关文章

  1. 九度OJ 1352 和为S的两个数字

    题目地址:http://ac.jobdu.com/problem.php?pid=1352 题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和 ...

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

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

  3. 九度OJ 1357:疯狂地Jobdu序列 (数字特性)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:715 解决:263 题目描述: 阳仔作为OJ的数据管理员,每一周的题目录入都让其很抓狂,因为题目不是他出的,他控制不了出题的速度--在等题目 ...

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

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

  5. 九度OJ 1370 数组中出现次数超过一半的数字

    题目地址:http://ac.jobdu.com/problem.php?pid=1370 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2 ...

  6. 九度oj 题目1256:找出两个只出现了一次的数字

    题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 输入的第一行包括一个整数N(1<=N<=1000). 接下来的一行包括N个 ...

  7. 九度oj 题目1087:约数的个数

    题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...

  8. 九度OJ 1502 最大值最小化(JAVA)

    题目1502:最大值最小化(二分答案) 九度OJ Java import java.util.Scanner; public class Main { public static int max(in ...

  9. 九度OJ,题目1089:数字反转

    题目描述: 12翻一下是21,34翻一下是43,12+34是46,46翻一下是64,现在又任意两个正整数,问他们两个数反转的和是否等于两个数的和的反转. 输入: 第一行一个正整数表示测试数据的个数n. ...

随机推荐

  1. 编译安装Nginx和php搭建KodExplorer网盘

    编译安装Nginx和php搭建KodExplorer网盘 环境说明: 系统版本    CentOS 6.9 x86_64         软件版本    nginx-1.12.2        php ...

  2. Linux学习之二-Linux系统的目录结构

    Linux学习之二-Linux系统的目录结构 在Linux的根目录下,有很多的目录,但是需要记住,对于Linux而言,一切皆文件.因此此处的目录也是文件.用ls / 命令就能看到根目录下的各类不同的目 ...

  3. 2017.7.12 IDEA热部署(更新jsp或java代码不用重启tomcat即可即时生效)

    选择war explored. 主要在于 On frame deactivation选项配置选择为 Update classes and resourses(当且仅当在Deployment配置页,对应 ...

  4. nginx资源争夺问题

    nginx资源争夺问题 多个配置之间存在资源争夺的情况,需要进行整理: 学习了:https://blog.csdn.net/veryisjava/article/details/72917894 ng ...

  5. [React] Use react-rewards to add microinteractions to React app to reward users for some actions

    It's important that our users enjoy using our application or website. One way we can make it happen ...

  6. 倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 81.0怎么办

    同步周期有问题   请确认MOTION的伺服周期是一致的,最好跟MAIN主程序也一样,所有周期都是2ms即可     更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.yo ...

  7. python数据类型整理

    Python中常见的数据结构可以统称为容器(container).序列(如列表和元组).映射(如字典)以及集合(set)是三类主要的容器. 一.序列(列表.元组和字符串) 序列中的每个元素都有自己的编 ...

  8. 【VBA】VBA编写的,将一列中相同的内容的行提取出来单独生成文件

    数据如上图所示,点击RUN后的运行结果如下: 得到该文件夹,文件夹内容如上图. 代码如下: Private Sub Command_OLIVER() Dim arr arr = Range(" ...

  9. Database returned an invalid value in QuerySet.datetimes(). Are time zone definitions for your datab

    Database returned an invalid value in QuerySet.datetimes(). Are time zone definitions for your datab ...

  10. R语言初识

    # 创建数据集&基本数据管理1.向量 创建函数 c() a <- c(1,2,3,4) a[c(i,j)] :[]给定元素所处位置的数值,即向量a中第i和第j个元素,a[2]第二个元素即 ...