二进制搜索答案算法

时间:2014-01-07 15:15:58

标签: c++ search binary

我想帮助我解决一个我被困2天的算法问题。我知道问题可以通过二元搜索答案来解决,但我找不到解决方案。

问题是:      在某些日子之前,已经建造了一条新的道路。道路的长度在左侧和右侧是无限的。道路上的售货亭安装有很多应用,每个业主在道路上都有一个更好的位置来安装他的售货亭(一个整数变量a [i]),但道路上的每个售货亭都必须距离前一个位置最远的k。每个位置都有不止一个应用程序(b [i])。问题是找到自助终端必须行进最多所需的最小距离。输入为n =坐标数,k =两个连续信息亭的距离,a [i] =应用程序的坐标,b [i] =应用程序的数量。输出应该是双精度的十进制数,表示已经走过最多的信息亭的最小距离.a [i]整数是离散的并按升序排序。让我们考虑例如输入:

3 2

0 1

3 2

6 1

输出:1.00

2 2

0 3

1 1

输出:2.50

3 1

0 5

2 1

4 5

输出:3.00

提前致谢!

我的想法是尽量减少两个极端信息亭(距离较长的信息亭)从初始位置开始的距离。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<float.h>
#define MAX 10000000
double a[MAX],b[MAX],sum,k;
long long int n;
double min_last=1000000;
int find(double c){
  int flag=0;
  long long int i;
  double pos=c;
 // printf("inside f\n");
 // printf("%lld\n",sum);
  long long  kiosks=0;
 // printf("x=%llf\n",c);
  if(fabsf((a[0]+pos+k*(sum-1)-a[n-1]))<min_last){
     // min_last=fabs((a[0]+c+k*(sum-1)-a[n-1]));
    // printf("min_last:%lf\n",min_last);
  for( i=0;i<sum;i++){
      if(pos<=sum+a[n-1]){
         kiosks++;
//  printf("%lld %lf\n",kiosks,c);
     pos=pos+k;
         if((kiosks==sum)){
           flag=1;
       min_last=fabsf((a[0]+c+k*(sum-1)-a[n-1]));
    // printf("%lf\n",min_last);}
    }
    }
  }
}
  // printf("%d\n",flag);
   return flag;
}
double binarySearch(){
 //  printf("inside binary\n");
    double low,high,mid;
   low=-sum*k-a[n-1];
   high=sum*k+a[n-1];
  while(low<high){
       mid=low+(high-low)/2.0;
       if(find(mid)==1){
      printf("%lf\n",mid);
          low=mid;
       }
       else
          high=mid-1;
}
  return low;
}
int main(){
   long long int i;
   double x,start;
   double posx;
   double low,high,mid;
   printf("Give n,k:");
   scanf("%lld %lf",&n,&k);
  // printf("%lld %lld\n",n,k);
   printf("Give the arrays\n");
   sum=0;
  // printf("sum=%llf\n",sum);
   for(i=0;i<n;i++){
//printf("%lld\n",i);
      scanf("%lf %lf",&a[i],&b[i]);
      sum=sum+b[i];
    }
  printf("%lf\n",binarySearch());
//printf("low=%lf\n",low);
start=low;
for(i=0;i<sum;i++){
      printf("kiosk %lld :%lf\t",i,start);
      start=start+k;}
      printf("\n");
return 0;
}

1 个答案:

答案 0 :(得分:0)

您可以选择使用std::equal_rangestd::lower_boundstd::upper_bound。它们是内置的C ++二进制搜索功能。