21. 通讯基站

某国有 N 个军事基地,每一个军事基地的位置可以由二维坐标平面上的一个点 (x, y) 表示。现在,这个国家的元首希望建立一个军事通讯基站。由于某些原因,这个军事通讯基站只能建立在 x 轴上的某个位置。现在,元首想要知道,新建立的基站到这 N 个军事基地的最大距离的最小值是多少。

输入

每个输入文件仅包含一组测试用例。

测试用例第一行输入一个整数 N (1 <= N <= 100’000),表示军事基地的数量。

接下来 N 行,每行包含两个以空格分隔的整数 x 与 y (-10’000 <= x, y <= 10’000),表示每一个军事基地的位置坐标。

输出

在单独的一行上输出一个保留到小数点后4位的小数表示答案。

样例解释

对于给出的样例,通讯基站建立在 (0, 0) 处时其到三个军事基地的距离最大值为 2。可以证明 2 为可能的最小值。

测试用例
in:
3
0 0
2 0
0 2
out:
2.0000↵

1024节来水个勋章玩玩。这题使用三分搜索,因为基站与各点位置是下凸函数。写两个函数,findmax(x)用于找点与x的最大距离另一个find(left,right)用于三分查找。我们在主程序输入的时候先顺便找出输入x的min与max,作为第一组left和right,执行find程序的时候,首先将上下界三分,用findmax比较两个三分点temp1、temp2,如果findmax(temp1)>findmax(temp2),则直接递归执行find(temp1,right),反之执行find(left,temp2)。最后当right-left<0.0001时输出findmax(left)并return,就OK了。需要注意的是,数据类型要采用double。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct node
{
	double x,y;
}point;
int N;
point p[100005];
double calulate(double x)
{
	double r=0;
	for(int i=0;i<N;i++)
		r=r>sqrt((x-p[i].x)*(x-p[i].x)+p[i].y*p[i].y)?r:sqrt((x-p[i].x)*(x-p[i].x)+p[i].y*p[i].y);
	return r;
}
double search(double left,double right)
{
	if(right-left>0.00001)
	{
		double t1=(2*left+right)/3;
		double t2=(left+2*right)/3;
		if(calulate(t1)>calulate(t2))
			search(t1,right);
		else
			search(left,t2);
	}
	else
		return calulate(left);
}
int main()
{
	double l=10000,r=-10000;
	scanf("%d",&N);
	for(int i=0;i<N;i++)
		scanf("%lf%lf",&p[i].x,&p[i].y);
	for(int i=0;i<N;i++)
	{
		if(r<=p[i].x)
			r=p[i].x;
		if(l>=p[i].x)
			l=p[i].x;
	}
	printf("%.4lf\n",search(l,r));
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ArgentumHook/article/details/83351126
21.