2020牛客寒假算法基础集训营第五场 B. 牛牛战队的比赛地(三分搜索)

题目传送门

题目描述

由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标(x,y)(x,y)。
这周末,牛牛队又要出去比赛了,各个比赛的赛点都在xx轴上。牛牛战队为了方便比赛,想找一个到达训练基地最大距离最小的地方作为比赛地。
这个问题对于牛牛战队太简单了,它就交给了你,你来帮他算一下~

输入描述:

输入数据第一行包含一个整数N(1≤N≤100000),表示牛牛战队训练基地的数量。
接下来NN行,每行包括22个整数x,y(−10000≤x,y≤10000),表示每一个训练基地的坐标。

输出描述:

输出一个小数,表示选择的比赛地距离各训练基地最大距离的最小值。
如果你的答案是aa,标准答案是bb,当max(1,∣b∣)/∣a−b∣ ≤10^−4
时,你的答案将被判定为正确。

示例1

输入

3
0 0
2 0
0 2

输出

2

说明

当在(0,0)(0,0)比赛时,到三个训练基地的最大距离是2。可以证明这是最小值。

思路:怎么说呢,之前也不会三分,二分想了很久也不知道改怎么分,也时赛后学习到的,本题所求的所有最大值是一个凹型的曲线,那么怎么找到最小的呢,就是找一下这填曲线的极值点,首先确定它的极小值点所在的区间为[l,r],本题可以设为[-1e5,1e5]

计算出两个三分点:

mid=(l+r)/2

mid2=(mid+r)/2

(其实这两个点的位置是灵活的)

此时 l < mid <mid2 < r

计算出对应的函数值 f(mid)和f(mid2)。

当f(mid)<f(mid2)时,则极小值点一定不会在mid2和r之间。

反之f(mid)>f(mid2)时,极小值点一定该不会在l和mid之间。

因此,当f(mid)<f(mid2)时,极小值点在[l,mid2]内。此时令l=l,r=mid2继续计算。

当f(mid)>f(mid2)时,极小值点在[mid,r]内。此时令l=mid,r=r继续计算。

直到这个区间足够小,可以认为l=r时,l就是所求的极小值点。(可接受的误差内)

算法复杂度大约是log1.5((r-l)/eps)。

代码思想上面说的比较清楚,就不再写注释。
本题AC代码

#include<bits/stdc++.h>
using namespace std;
typedef double dou;
typedef long long ll;
const int maxn=1e6+100;
struct node{
	double x,y;
}a[maxn];
ll n;
double check(double x)//得到函数值
{
	double ma=0;
	for(int i=1;i<=n;i++)
	{
		if(sqrt((a[i].x-x)*(a[i].x-x)+a[i].y*a[i].y)>ma)
		ma=sqrt((a[i].x-x)*(a[i].x-x)+a[i].y*a[i].y);
		
	}
	return ma;
}
int main()
{

	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i].x>>a[i].y;
	}
	double l=-1e4,r=1e4;
	double mid,midmid;
	for(int i=1;i<=100;i++)
	{
		mid=(l+r)/2;
	    midmid=(mid+r)/2;
	    if(check(midmid)>check(mid))r=midmid;
	    else l=mid;
	}
	printf("%.10lf\n",check(l));
}

今天是情人节,看到这篇博客的程序员们,辛苦啦,祝愿大家早日脱单!QAQ

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值