タイトルの説明
Niu Niuチームは外出する必要があることが多いため、全国に多くのトレーニング拠点が設置されており、各拠点には座標(x、y)があります。
今週末、Niu Niuチームは再びプレーし、各ゲームのポイントはX軸にあります。ゲームを円滑に進めるために、Niu Niuチームはトレーニング拠点までの距離が最も短い場所をゲームの場所として見つけたいと考えています。
この質問はNiu Niuチームにとって単純すぎるため、あなたに渡されます。あなたが彼がそれを計算するのを助けることができます〜
説明を入力してください
入力データの最初の行には整数N(1≤N≤100000)が含まれ、これはNiu Niuチームのトレーニングベースの数を表します。
次のN行。各行には2つの整数x、y(-100000≤x、y≤10000)が含まれ、各トレーニングベースの座標を表します。
出力の説明
小数が出力されます。これは、選択した競技場所と各トレーニングベースの間の最大距離の最小値を表します。
あなたの答えがある場合と、標準の答えは、Bです 時間は、あなたの答えが真であると判断されます。
入力例
3
0 0
2 0
0 2
出力例
2
分析:
X軸上の任意の点について、n点からの最大距離はです 。ここで、距離の代わりに距離の2乗が使用され、効果は同じです。
これは、複数の2次関数の最大値であることがわかります。
このような関数には、次のプロパティがあります。
1.関数が複数の下向き凸関数の最大値である場合、この関数は最初に減少し、次に増加することができ、この関数も下向き凸関数です;
2.関数が複数の上向き凸関数の最小値である場合、これはこの関数は最初に増加し、次に減少するだけです。その後、この関数も凸関数です。
したがって、上記の関数は下に凸の関数です。
したがって、下に凸の関数の最小値を見つけることに変換されます。これは、間隔を3で連続的に除算することによって取得できます。
具体的な説明については、コードを参照してください。
#include<iostream>
#include<cmath>
using namespace std;
struct coord
{
double x,y;
}A[100005];
double ans,l,r,mid,X;
int n;
const double eps = 1e-6;//精度设置
double check(double x){ //求出当前的点到N个点的最大值,即max函数对应点的值
double tmax=0;
for(int i = 0;i < n;++i){
double dis = sqrt((A[i].x-x)*(A[i].x-x)+A[i].y*A[i].y);
tmax=max(tmax,dis);
}
return tmax;
}
double tsearch(double left,double right){
int i;
double mid,midmid;
for(i=0;i<100;i++){ //循环100次,其实可以小一点,满足精度要求即可
mid=left+(right-left)/2; //区间中点
midmid=mid+(right-mid)/2; //左半区间中点
if(check(mid)>check(midmid)) //极大值求法
left=mid;
else
right=midmid;
}
return mid;
}
int main(){
scanf("%d",&n);
l = 10005;
r = -10005;
int x,y;
for(int i = 0;i < n;++i)
{
scanf("%d%d",&x,&y);
A[i].x=x;
A[i].y=y;
if(A[i].x < l) l = A[i].x;
if(A[i].x > r) r = A[i].x;//寻找左右边界l,r
}
ans=tsearch(l,r);
printf("%.9lf\n",check(ans));
return 0;
}