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>
4int fun(int a[],int n,int t)
5 {
6int L,R,mid;
7int x,y;
8    L=0;R=n-1;
9while(L<=R)
10    {
11        mid=L+(R-L)/2;
12if(a[mid]==t) return a[mid];
13else if(a[mid]<t) L=mid+1;
14else R=mid-1;
15    }
16    x=abs(a[L]-t);
17    y=abs(a[R]-t);
18if(x<y) return a[L];
19else if(x>y) return a[R];
20else return (a[L]<a[R]?a[L]:a[R]);
21 }
22int main(int argc, char *argv[])
23 {
24int n,a[100003],m,t,i,res;
25    scanf("%d",&n);
26for(i=0;i<n;i++) scanf("%d",&a[i]);
27    scanf("%d",&m);
28for(i=0;i<m;i++)
29    {
30        scanf("%d",&t);
31
32if(t<a[0]) res=a[0];
33else if(t>a[n-1]) res=a[n-1];
34else res=fun(a,n,t);
35
36        printf("%d\n",res);
37    }
38return0;
39 }
View Code
这⾥对上述代码做⼀个样例跟踪演⽰:
假设⽬标t=10048.序列如下:
上图描述的是⽬标t=10048时,上述程序执⾏过程中⼆分查函数⾥⾯L与R的变化过程。下⾯是另⼀个
代码,跟上述的思路基本⼀致。
1//来⾃ttps://blog.csdn/qq_33837704/article/details/80314377
2 #include<iostream>
3 #include<string.h>
4using namespace std;
5int n,m,target;
6int base,top,mid=0;
7long long nums[100010];
8int main(){
9    memset(nums,-1,sizeof(nums));
10    cin>>n;
11for(int i=0;i<n;i++){
12        cin>>nums[i];
13    }
14    cin>>m;
15while(m--){
16        cin>>target;
17base=0;
18        top=n-1;
19while(base<=top){
20            mid=(base+top)/2;
21if(nums[mid]==target){
22break;;
23            }else if(nums[mid]<target){
24base=mid+1;
25            }else {
26                top=mid-1;
27            }
28        }
29if(nums[mid]==target){
30            cout<<target<<endl;
31        }else{
32if(base>=n||base<0){
33                cout<<nums[top]<<endl;
34            }else if(top>=n||top<0){
35                cout<<nums[base]<<endl;
36            }else{
37if(abs(nums[base]-target)>abs(nums[top]-target)){
38                    cout<<nums[top]<<endl;
39                }else{
40if(abs(nums[base]-target)<abs(nums[top]-target)){
41                        cout<<nums[base]<<endl;
42                    }else{
43if(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>
3int main(int argc, char *argv[])
4 {
5int n,i,*a,m,t;
6int begin,end,mid;
7int x,y;
8
9    scanf("%d",&n);
10    a=(int *)malloc(n*sizeof(int));
11for(i=0;i<n;i++) scanf("%d",&a[i]);
12
13    scanf("%d",&m);
14for(i=0;i<m;i++)
15    {
16        scanf("%d",&t);
17if(a[0]>t) { printf("%d\n",a[0]); continue;}
18else if(a[n-1]<t) { printf("%d\n",a[n-1]); continue;}
19
20        begin=0;
21        end=n-1;
22        mid=(begin+end)/2;
23while(begin<=end)  //while(end-begin>1)
24        {
25if(a[mid]==t) { printf("%d\n",a[mid]);break;}printf怎么读的
26else
27            {
28if(a[mid]>t)
29                {
30                    end=mid-1;
31                }
32else
33                {
34                    begin=mid+1;
35                }
36            }
37            mid=(begin+end)/2;
38        }
39if(a[mid]!=t)
40        {
41            x=abs(a[begin]-t);
42            y=abs(a[end]-t);
43if(x<y) printf("%d\n",a[begin]);
44else if(x>y) printf("%d\n",a[end]);
45else printf("%d\n",(a[begin]<a[end]?a[begin]:a[end]));
46        }
47    }
48free(a);
49return0;
50 }
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<math.h>
4int fun(int a[],int n,int t)
5 {
6int L,R,mid;
7int x,y;
8    L=0;R=n-1;
9while(L<=R)
10    {
11        mid=L+(R-L)/2;
12if(a[mid]==t) return a[mid];
13else if(a[mid]<t) L=mid+1;
14else R=mid-1;
15    }
16    x=abs(a[L]-t);
17    y=abs(a[R]-t);
18if(x<y) return a[L];
19else if(x>y) return a[R];
20else return (a[L]<a[R]?a[L]:a[R]);
21 }
22int main(int argc, char *argv[])
23 {
24int n,a[100003],m,t,i,res;
25    scanf("%d",&n);
26for(i=0;i<n;i++) scanf("%d",&a[i]);
27    scanf("%d",&m);
28for(i=0;i<m;i++)
29    {
30        scanf("%d",&t);
31if(n==1) res=a[0]; //这个重要
32else if(t<a[0]) res=a[0];//这个重要
33else if(t>a[n-1]) res=a[n-1];//这个重要34else res=fun(a,n,t);
35
36        printf("%d\n",res);
37    }
38return0;
39 }
View Code

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。