zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Python 安装Twisted 提示python version 2.7 required,which was not found in the registry
    Openfire Strophe开发中文乱码问题
    css div 垂直居中
    How to create custom methods for use in spring security expression language annotations
    How to check “hasRole” in Java Code with Spring Security?
    Android 显示/隐藏 应用图标
    Android 当媒体变更后,通知其他应用重新扫描
    文件上传那些事儿
    专题:点滴Javascript
    主流动画实现方式总结
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/6882821.html
Copyright © 2011-2022 走看看