• 01:查找最接近的元素


    http://noi.openjudge.cn/ch0111/01/

    01:查找最接近的元素

    总时间限制: 1000ms 内存限制: 65536kB
    描述

    在一个非降序列中,查找与给定值最接近的元素。

    输入
    第一行包含一个整数n,为非降序列长度。1 <= n <= 100000。
    第二行包含n个整数,为非降序列各元素。所有元素的大小均在0-1,000,000,000之间。
    第三行包含一个整数m,为要询问的给定值个数。1 <= m <= 10000。
    接下来m行,每行一个整数,为要询问最接近元素的给定值。所有给定值的大小均在0-1,000,000,000之间。
    输出
    m行,每行一个整数,为最接近相应给定值的元素值,保持输入顺序。若有多个值满足条件,输出最小的一个。
    样例输入
    3
    2 5 8
    2
    10
    5
    样例输出
    8
    5

    经典的二分查找问题。这里新添加两段比较好的代码:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<math.h>
     4 int fun(int a[],int n,int t)
     5 {
     6     int L,R,mid;
     7     int x,y;
     8     L=0;R=n-1;
     9     while(L<=R)
    10     {
    11         mid=L+(R-L)/2;
    12         if(a[mid]==t) return a[mid];
    13         else if(a[mid]<t) L=mid+1;
    14         else R=mid-1;
    15     }
    16     x=abs(a[L]-t);
    17     y=abs(a[R]-t);
    18     if(x<y) return a[L];
    19     else if(x>y) return a[R];
    20     else return (a[L]<a[R]?a[L]:a[R]);
    21 }
    22 int main(int argc, char *argv[])
    23 {
    24     int n,a[100003],m,t,i,res;
    25     scanf("%d",&n);
    26     for(i=0;i<n;i++) scanf("%d",&a[i]);
    27     scanf("%d",&m);
    28     for(i=0;i<m;i++)
    29     {
    30         scanf("%d",&t);
    31         
    32         if(t<a[0]) res=a[0];
    33         else if(t>a[n-1]) res=a[n-1];
    34         else res=fun(a,n,t);
    35         
    36         printf("%d
    ",res);
    37     }
    38     return 0;
    39 }
    View Code

    这里对上述代码做一个样例跟踪演示:

    假设目标t=10048.序列如下:

    上图描述的是目标t=10048时,上述程序执行过程中二分查找函数里面L与R的变化过程。

    下面是另一个代码,跟上述的思路基本一致。

     1 //来自ttps://blog.csdn.net/qq_33837704/article/details/80314377
     2 #include<iostream>
     3 #include<string.h>
     4 using namespace std;
     5 int n,m,target;
     6 int base,top,mid=0;
     7 long long nums[100010];
     8 int main(){
     9     memset(nums,-1,sizeof(nums));
    10     cin>>n;
    11     for(int i=0;i<n;i++){
    12         cin>>nums[i];
    13     }
    14     cin>>m;
    15     while(m--){
    16         cin>>target;
    17         base=0;
    18         top=n-1;
    19         while(base<=top){
    20             mid=(base+top)/2;
    21             if(nums[mid]==target){
    22                 break;;
    23             }else if(nums[mid]<target){
    24                 base=mid+1;
    25             }else {
    26                 top=mid-1;
    27             }
    28         }
    29         if(nums[mid]==target){
    30             cout<<target<<endl;
    31         }else{
    32             if(base>=n||base<0){
    33                 cout<<nums[top]<<endl;
    34             }else if(top>=n||top<0){
    35                 cout<<nums[base]<<endl;
    36             }else{
    37                 if(abs(nums[base]-target)>abs(nums[top]-target)){
    38                     cout<<nums[top]<<endl;
    39                 }else{
    40                     if(abs(nums[base]-target)<abs(nums[top]-target)){
    41                         cout<<nums[base]<<endl;
    42                     }else{
    43                         if(base<top){
    44                             cout<<nums[base]<<endl;
    45                         }else{
    46                             cout<<nums[top]<<endl;
    47                         }
    48                     }
    49                 }
    50             }
    51         }
    52     }
    53 }
    View Code

     假设目标t=10092,那么二分过程如下:

     假设目标t=10006,那么二分查找过程如下:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 int main(int argc, char *argv[])
     4 {
     5     int n,i,*a,m,t;
     6     int begin,end,mid;
     7     int x,y;
     8     
     9     scanf("%d",&n);
    10     a=(int *)malloc(n*sizeof(int));
    11     for(i=0;i<n;i++) scanf("%d",&a[i]);
    12     
    13     scanf("%d",&m);
    14     for(i=0;i<m;i++)
    15     {
    16         scanf("%d",&t);
    17         if(a[0]>t) { printf("%d
    ",a[0]); continue;}
    18         else if(a[n-1]<t) { printf("%d
    ",a[n-1]); continue;}
    19         
    20         begin=0;
    21         end=n-1;
    22         mid=(begin+end)/2;
    23         while(begin<=end)   //while(end-begin>1)
    24         {
    25             if(a[mid]==t) { printf("%d
    ",a[mid]);break;}
    26             else 
    27             {
    28                 if(a[mid]>t)
    29                 {
    30                     end=mid-1;
    31                 }
    32                 else 
    33                 {
    34                     begin=mid+1;
    35                 }
    36             }
    37             mid=(begin+end)/2;
    38         }
    39         if(a[mid]!=t)
    40         {
    41             x=abs(a[begin]-t);
    42             y=abs(a[end]-t);
    43             if(x<y) printf("%d
    ",a[begin]);
    44             else if(x>y) printf("%d
    ",a[end]);
    45             else printf("%d
    ",(a[begin]<a[end]?a[begin]:a[end]));
    46         }
    47     }
    48     free(a);
    49     return 0;
    50 }
     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<math.h>
     4 int fun(int a[],int n,int t)
     5 {
     6     int L,R,mid;
     7     int x,y;
     8     L=0;R=n-1;
     9     while(L<=R)
    10     {
    11         mid=L+(R-L)/2;
    12         if(a[mid]==t) return a[mid];
    13         else if(a[mid]<t) L=mid+1;
    14         else R=mid-1;
    15     }
    16     x=abs(a[L]-t);
    17     y=abs(a[R]-t);
    18     if(x<y) return a[L];
    19     else if(x>y) return a[R];
    20     else return (a[L]<a[R]?a[L]:a[R]);
    21 }
    22 int main(int argc, char *argv[])
    23 {
    24     int n,a[100003],m,t,i,res;
    25     scanf("%d",&n);
    26     for(i=0;i<n;i++) scanf("%d",&a[i]);
    27     scanf("%d",&m);
    28     for(i=0;i<m;i++)
    29     {
    30         scanf("%d",&t);
    31         if(n==1) res=a[0]; //这个重要 
    32         else if(t<a[0]) res=a[0];//这个重要
    33         else if(t>a[n-1]) res=a[n-1];//这个重要
    34         else res=fun(a,n,t);
    35         
    36         printf("%d
    ",res);
    37     }
    38     return 0;
    39 }
    View Code
  • 相关阅读:
    快速入门系列--GIT版本控制工具
    快速入门系列--NOSQL--05Redis也木有那么“高富帅”
    apt下载open-jdk8报错add-apt-repository: command not found
    jenkins-参数化构建(三)插件:Git Parameter
    jenkins-参数化构建(二)插件:Extended Choice Parameter
    jenkins-参数化构建(一)
    Jenkins-权限管理
    redis安装
    elk-图形化展示(八)
    elk-(七)
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/6882821.html
Copyright © 2020-2023  润新知