二分练习(SDUT 2781)

来源:互联网 发布:外汇交易分析软件 编辑:程序博客网 时间:2024/05/16 11:23

二分练习

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

给你一个序列,然后给你m个元素,让你从序列中找出与每个元素最接近的数字输出来,如果有两个就输出两个。
 

输入

 多组输入,第一行给你两个数n(0 < n < 10000000),m(0 < m < n),接下来是数列的n个数,然后再输入m个元素,让你找出最接近每个元素的值。如果有两个,按从小到大输出。
 

输出

 这m个数分别输出最接近每个元素的值,组与组之间输出一个空行。

示例输入

8 41 2 3 4 5 6 8 114927

示例输出

4826 8

提示

 

来源

lwn

示例程序


一晚上都耗在这道题上了,二分的变形问题,因为涉及的数有多个,传统的不好确定位置,所以得求出它的上下界函数,在这个的基础上展开求。在此多谢赵鹏学长,orz~



#include <stdio.h>#include <string.h>#include <stdlib.h>#include <algorithm>using namespace std;int x[10000010];int  down(int a[],int low,int high, int key)//求下界函数,即小于key的最大值;{    int res=-1;    while (low<=high)//注意等号    {        int mid=(high+low)/2;         if(a[mid]<=key)        {            low=mid+1;            res=mid;        }        else            high=mid-1;    }    return res;}int up(int a[],int low,int high,int key)//求上界函数,即大于key的最小值;{    int res=-1;    while (low<=high)    {        int mid=(low+high)/2;         if(a[mid]<key)            low=mid+1;        else        {            res=mid;            high=mid-1;        }    }    return res;}int main(){    int n,m,i;    int nmax,nmin,key;    while(~scanf("%d %d",&n,&m))    {        for(i=0;i<n;i++)            scanf("%d",&x[i]);        sort(x,x+n);        while (m--)        {            scanf("%d",&key);            nmax=up(x,0,n-1,key);            nmin=down(x,0,n-1,key);           if(nmin==-1)//这个需要判断一下,因为不一定能求到比它小的数;            {                printf("%d\n",x[nmax]);            }            else if(nmax==-1)//同样,这个不一定能求到比它大的数;            {                printf("%d\n",x[nmin]);            }             else if(x[nmax]==x[nmin])//上下界函数求到一样的值,即key值,直接输出;                printf("%d\n",x[nmin]);            else            {                if(key-x[nmin]==x[nmax]-key)//key值没有,左右两个差值一样,即输出;                    printf("%d %d\n",x[nmin],x[nmax]);                else if(key-x[nmin]<x[nmax]-key)                printf("%d\n",x[nmin]);                else                    printf("%d\n",x[nmax]);            }        }        printf("\n");//审清题,别忘记这个;    }    return 0;}


0 0
原创粉丝点击