zoukankan      html  css  js  c++  java
  • 九度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
    ",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
    ",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
    ",mina, minb);
    33     }
    34     return 0;
    35 }

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

  • 相关阅读:
    Swift Optional
    cocoapods 配置
    winform窗体全屏
    SQLiteDatabase的使用
    探索Gallery和ImageSwitcher布局
    常用布局参考
    增加动画的效果
    AlertDialog的写法
    自定义Toast
    适配器的经典写法
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5803824.html
Copyright © 2011-2022 走看看