题目描述
由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标(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