zoukankan      html  css  js  c++  java
  • 九度OJ 1352:和为S的两个数字 (查找)

    时间限制: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
    ");
            else
                printf("%d %d
    ", 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
    ");
            else
                printf("%d %d
    ", a[i], a[j]);
        }
     
        return 0;
    }
    /**************************************************************
        Problem: 1352
        User: liangrx06
        Language: C
        Result: Accepted
        Time:1450 ms
        Memory:4748 kb
    ****************************************************************/


    
    

  • 相关阅读:
    Spring boot unable to determine jdbc url from datasouce
    Unable to create initial connections of pool. spring boot mysql
    spring boot MySQL Public Key Retrieval is not allowed
    spring boot no identifier specified for entity
    Establishing SSL connection without server's identity verification is not recommended
    eclipse unable to start within 45 seconds
    Oracle 数据库,远程访问 ora-12541:TNS:无监听程序
    macOS 下安装tomcat
    在macOS 上添加 JAVA_HOME 环境变量
    Maven2: Missing artifact but jars are in place
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5083781.html
Copyright © 2011-2022 走看看