九度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

今天状态真是差劲
一开始的代码如下
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7  
 8 int num[1000002];
 9  
10 int main(int argc, char const *argv[])
11 {
12     int n, k;
13     while(scanf("%d %d",&n,&k) != EOF) {
14         for(int i = 0; i < n; i++) {
15             scanf("%d",&num[i]);
16         }
17         int iptr = 0;
18         int mina = -1, minb = -1;
19         while(iptr < n) {
20             int p = k - num[iptr];
21             int t = lower_bound(num, num + n, p) - num;
22             if(num[t] == p && t > iptr) {
23                     mina = num[iptr];
24                     minb = p;
25                     break;
26             }
27             iptr++;
28         }   
29         printf("%d %d\n",mina, minb);
30     }
31     return 0;
32 }

思路很简单,用二分搜索找到另一个值在数组中的位置。结果反复提交都是错误

问题:lower_bound返回的是num[i]>=p的指针的最小值,

如果输入

5 2

1 1 1 2 5就会出错 

改正

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 int num[1000002];
 9 
10 int main(int argc, char const *argv[])
11 {
12     int n, k;
13     while(scanf("%d %d",&n,&k) != EOF) {
14         for(int i = 0; i < n; i++) {
15             scanf("%d",&num[i]);
16         }
17         int iptr = 0;
18         int mina = -1, minb = -1;
19         while(iptr < n && num[iptr] * 2 <= k) {
20             int p = k - num[iptr];
21             int t = upper_bound(num, num + n, p) - num - 1;
22             if(num[t] == p && t > iptr) {
23                     mina = num[iptr];
24                     minb = p;
25                     break;
26             }
27             iptr++;
28         }    
29         printf("%d %d\n",mina, minb);
30     }
31     return 0;
32 }

其实此题还有一种更好的解法

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 int num[1000002];
 9 
10 int main(int argc, char const *argv[])
11 {
12     int n, k;
13     while(scanf("%d %d",&n,&k) != EOF) {
14         for(int i = 0; i < n; i++) {
15             scanf("%d",&num[i]);
16         }
17         int low = 0, high = n-1;
18         int mina = -1, minb = -1;
19         while(low < high) {
20             if(num[low] + num[high] == k) {
21                 mina = num[low];
22                 minb = num[high];
23                 break;
24             }
25             else if(num[low] + num[high] < k) {
26                 low++;
27             }
28             else {
29                 high--;
30             }
31         }
32         printf("%d %d\n",mina, minb);
33     }
34     return 0;
35 }

注意找到的第一个便是乘积最小的!!!

posted @ 2016-08-24 17:14  Jason杰  阅读(181)  评论(0编辑  收藏  举报