九度OJ-题目1352:和为S的两个数字
2015-06-12 15:46
393 查看
题目链接地址:
九度OJ-题目1352:和为S的两个数字
题目描述:
输入一个递增排序的数组和一个数字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
解题思路:
从题目中可以提取出两个关键词:“递增排序的数组”,“乘积最小”。
依稀记得中学时学过一个定理:和相等的两个数,两数差越大,他们的乘积越小。
而数组又是递增有序的,因此我想出了以下解法:
从数组number的最左端number[left] (left = 0)和最右端number[right] (right = n-1)同时向数组的中间逼近,
(1)如果number[left]与number[right]之和大于S,则令right--;
(2)如果number[left]与number[right]之和小于S,则令left++;
(3)如果number[left]与number[right]之和等于S,则停止逼近,输出这两个数。
举个栗子,对于测试用例1 2 4 7 11 15
找出和等于15的两个数的具体过程如下:
因为1 + 15 > 15,所以数组左端不变,右端向左逼近到数字11;
因为1 + 11 < 15,所以数组右端不变,左端向右逼近到数字2;
因为2 + 11 < 15,所以数组右端不变,左端向右逼近到数字4;
因为4 + 11 = 15,所以4和11就是满足条件的两个数。
AC代码如下:
九度OJ-题目1352:和为S的两个数字
题目描述:
输入一个递增排序的数组和一个数字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
解题思路:
从题目中可以提取出两个关键词:“递增排序的数组”,“乘积最小”。
依稀记得中学时学过一个定理:和相等的两个数,两数差越大,他们的乘积越小。
而数组又是递增有序的,因此我想出了以下解法:
从数组number的最左端number[left] (left = 0)和最右端number[right] (right = n-1)同时向数组的中间逼近,
(1)如果number[left]与number[right]之和大于S,则令right--;
(2)如果number[left]与number[right]之和小于S,则令left++;
(3)如果number[left]与number[right]之和等于S,则停止逼近,输出这两个数。
举个栗子,对于测试用例1 2 4 7 11 15
找出和等于15的两个数的具体过程如下:
因为1 + 15 > 15,所以数组左端不变,右端向左逼近到数字11;
因为1 + 11 < 15,所以数组右端不变,左端向右逼近到数字2;
因为2 + 11 < 15,所以数组右端不变,左端向右逼近到数字4;
因为4 + 11 = 15,所以4和11就是满足条件的两个数。
AC代码如下:
#include<stdio.h> #define MAX 1000001 int number[MAX]; // 用于保存整数的数组 /** * 输入长度为n的整形数组 * @param n 表示数组的长度 * @return void */ void inputNumberArray(int n) { int i; for(i = 0;i < n;i++) { scanf("%d",&number[i]); } } /** * 寻找数组中两个和等于S的数字 * @param n 数组的长度 * @param k k表示要求的两数之和 * @return void */ void findTwoNumberSumEqualsS(int n,int k) { int left,right; //令left = 0,right = n - 1,这样当找到number[left] + number[right]) == k,可以保证number[left]*number[right]的值最小 left = 0,right = n - 1; while(left <= right) { // 如果两个数之和等于k,则直接输出这两个 if((number[left] + number[right]) == k) { break; } // 如果两个数之和小于k,则令left++ else if((number[left] + number[right]) < k) { left++; } // 如果两个数之和大于k,则令right-- else { right--; } } if(left < right) printf("%d %d\n",number[left],number[right]); else printf("-1 -1\n"); } int main() { int n,k; while(EOF != scanf("%d%d",&n,&k)) { inputNumberArray(n); findTwoNumberSumEqualsS(n,k); } return 0; } /************************************************************** Problem: 1352 User: blueshell Language: C++ Result: Accepted Time:1440 ms Memory:4928 kb ****************************************************************/
相关文章推荐
- 微信的redirect_uri参数错误原因分析
- Scrapy 安装
- EF中的事务处理的初步理解
- apt-get程序和系统管理
- asp.net Url重写
- 基于Bootstrap3制作响应式布局网站(五)
- 做一个程序来查询手机号码的归属地(使用的是HttpURLConnection的post提交方式)
- putty快速设置本地代理
- 黑马程序员——java基础-IO(一)
- linux 常用命令 ln/cat/echo/find/xargs/grep/ssh/scp
- 新创建job不能自动执行
- Hdu 5236 Article(dp)
- ffmpeg源码跟踪之时间基转换,时间戳比较笔记
- C# List和String互相转换
- Microsoft.VisualStudio.DebuggerVisualizers.dll 文件位置 for VisualStudio 2015
- C 编程调试集
- linux下解决端口被占用问题
- 数据结构的排序用直接插入、折半插入、希尔排序、快速排序
- Mysql 数据库权限导出
- 使用java将多种类型的文件如Word、PDF、JPG汇总到一个文档中(Word或者PDF)