• 1001 数组中和等于K的数对 (51nod)


    基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题
    收藏
    关注
    给出一个整数K和一个无序数组A,A的元素为N个互不相同的整数,找出数组A中所有和等于K的数对。例如K = 8,数组A:{-1,6,5,3,4,2,9,0,8},所有和等于8的数对包括(-1,9),(0,8),(2,6),(3,5)。
     
    Input
    第1行:用空格隔开的2个数,K N,N为A数组的长度。(2 <= N <= 50000,-10^9 <= K <= 10^9)
    第2 - N + 1行:A数组的N个元素。(-10^9 <= A[i] <= 10^9) 
    Output
    第1 - M行:每行2个数,要求较小的数在前面,并且这M个数对按照较小的数升序排列。
    如果不存在任何一组解则输出:No Solution。
    Input示例
    8 9
    -1
    6
    5
    3
    4
    2
    9
    0
    8
    Output示例
    -1 9
    0 8
    2 6
    3 5



    刚开始写的时候以为只是个简单的排完序然后逐个查找看是否有满足条件的即可,,,,没想到交了几发,居然超时了,,soga,原来时间复杂度到了O(n^2)...
    在查找方面需要优化,下面附上超时代码和AC代码,,然后去网上找了找,居然用到了lower_bound这个函数,
    超时代码
    #include<bits/stdc++.h>
    using namespace std;
    int num[50001];
    int main()
    {
        int k,n;
        cin>>k>>n;
        for(int i=0;i<n;i++)
        cin>>num[i];
        sort(num,num+n);
        int flag=0;
        for(int i=0;i<n;i++)
        {
          for(int j=n-1;j>i;j--)
          {
              if(num[i]+num[j]==k)
              {
                  cout<<num[i]<<" "<<num[j]<<endl;
                  flag=1;
              }
              
              
           } 
            
        }
        if(flag==0)
        cout<<"No Solution"<<endl;
        return 0;
    }

    AC代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int num[50001];
     4 int main()
     5 {
     6     int k,n;
     7     cin>>k>>n;
     8     for(int i=0;i<n;i++)
     9     cin>>num[i];
    10     sort(num,num+n);
    11     int flag=0;
    12   int i=0;
    13   int t=n-1;
    14   int sum;
    15   while(i<t)
    16   {
    17       sum=num[i]+num[t];
    18       if(sum==k)
    19       {
    20               printf("%d %d
    ",num[i++],num[t--]);
    21               flag=1;
    22       }
    23       
    24     else if(sum<k)
    25     i++;
    26     else
    27     t--;
    28 
    29   }
    30     if(flag==0)
    31     cout<<"No Solution"<<endl;
    32     return 0;
    33 }

    lower_bound解法

    #include "iostream"  
    #include <algorithm>  
    #define N 50006  
    using namespace std;  
      
    long long num[N];  
      
    int main()  
    {  
        long long k, n;  
        bool flag = true;  
        cin >> k >> n;  
        for (int i = 0; i < n; i++)  
        {  
            cin >> num[i];  
        }  
      
        sort(num, num + n);  
        for (int i = 0; i < n; i++)  
        {  
            int pos = lower_bound(num, num + n, k - num[i]) - num;  
            if (num[i] + num[pos] == k && pos > i)  
            {  
                cout << num[i] << " " << num[pos] << endl;  
                flag = false;  
            }  
              
        }  
        if (flag)  
        {  
            cout << "No Solution" << endl;  
        }  
      
        getchar();  
        getchar();  
        return 0;  
    }  

    借此机会,了解了lower_bound函数的一些用法

    该函数为C++ STL内的函数

    其包含在头文件#include <algorithm> 中

    注意事项

    调用lower_bound之前必须确定序列为有序序列,否则调用出错

    函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置

    举例如下:

    一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标

    pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。

    pos = lower_bound( number, number + 8, 9) - number, pos = 1,即number数组的下标为1的位置(即10所在的位置)。

    pos = lower_bound( number, number + 8, 111) - number, pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。

    所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!~

    返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置




  • 相关阅读:
    AutomationQA.com开始连载 TIB工作室核心成员 刘毅 的《软件测试自动化的探索与管理》专栏文章
    自动化测试项目实战训练【广州 5月、6月】
    大话“自动化测试框架思想与构建”
    ST&QA 2011年12期的杂志 已上传到AutomationQA资源共享
    整体思考自动化测试发展和价值回报
    热烈祝贺AutomationQA成为QA联盟核心会员!
    TestPartner中使用Module和Shared Module设计模块化结构的脚本
    [转] 自动化测试案例设计及读后感
    北京自动化测试实战训练课程下周开始
    后Web2.0的创新模式
  • 原文地址:https://www.cnblogs.com/lklk/p/9074029.html
Copyright © 2020-2023  润新知