现在的位置: 首页 > 综合 > 正文

二分法

2014年05月31日 ⁄ 综合 ⁄ 共 1609字 ⁄ 字号 评论关闭

二分练习


Time Limit: 1000MS Memory limit: 65536K

题目描述

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

输入

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

 

输出

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

示例输入

8 4
1 2 3 4 5 6 8 11
4
9
2
7

示例输出

4
8
2
6 8

提示

 

来源

lwn

示例程序

WA了好多次,终于对了,这陷阱好不给力啊
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
int main()
{
	int n,a[100010],i,a1,m,m1,l,v,j;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		
		for(i=0;i<n;i++)
		{scanf("%d",&a[i]); 
		
	}
	sort(a,a+n);
	for(i=0;i<m;i++)
	{
	 scanf("%d",&a1); 
   if(upper_bound(a,a+n,a1)-lower_bound(a,a+n,a1))
     {
     	printf("%d\n",a1);
		
     }
     else 
      {
      	m1=n-1;//终点 
      	v=0;//起点 
      	while(m1-v>1)
      	{
	      	l=(m1+v)/2;
	      	if(a[l]>a1)m1=l;
	      	else v=l;
	      }
	      if(fabs(a[m1]-a1)>fabs(a[v]-a1))
	      {printf("%d\n",a[v]);}
	      else if(fabs(a[m1]-a1)<fabs(a[v]-a1))
	      {printf("%d\n",a[m1]);}
	      else if(a[m1]-a1+a[v]-a1==0){printf("%d %d\n",a[v],a[m1]);}
	      else printf("%d\n",a[m1]);
      }
	}
	printf("\n");
	}
}

利用上下界函数

#include<stdio.h>
#include<algorithm>
using namespace std;
int upper(int a[], int n, int x)
{
    int lo = 0, hi = n - 1, mid;

    while (lo < hi)
    {
        mid = (lo + hi + 1) / 2;
        if (a[mid] <= x)
            lo = mid;
        else
            hi = mid - 1;
    }
    return lo;
}

int lower(int a[], int n, int x)
{
    int lo = 0, hi = n - 1, mid;

    while (lo < hi)
    {
        mid = (lo + hi) / 2;
        if (a[mid] >= x)
            hi = mid;
        else
            lo = mid + 1;
    }
    return lo;
}
int main()

{
    int n,m,i,l1,l2,key,x[10001111];
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%d",&x[i]);
        sort(x,x+n);
        while(m--)
        {
            scanf("%d",&key);
            l1=upper(x,n,key);
            l2=lower(x,n,key);
            //printf("%d %d\n",x[l1],x[l2]);
            if(x[l1]==x[l2])printf("%d\n",x[l1]);
            else
            {
                if((key-x[l1])==(x[l2]-key))
                    printf("%d %d\n",x[l1],x[l2]);
                else if((key-x[l1])<(x[l2]-key))
                    printf("%d\n",x[l1]);
                else printf("%d\n",x[l2]);
            }

        }printf("\n");
    }
    return 0;
}

抱歉!评论已关闭.