题意:
给你N个点,让你求出x坐标轴上一点到N个点中最大距离的最小值。
思路:
二分(答案具有严格单调性,容易验证答案是否正确)
这里check函数比较难想
参考用户:moyangxian
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 +7;
const double eps = 1e-8;
const ll MAXN = 1e6 + 5;
int n;
double x[MAXN],y[MAXN];
double ans1;
double ans2;
double ans;
bool check(double mid){
double xl=-10000.0;
double xr=10000.0;
for(int i=1;i<=n;i++){
if(mid<fabs(y[i])) return 0;//二分出来的答案连y都够不着
double d=sqrt(mid*mid-y[i]*y[i]);
xl=max(xl,x[i]-d);
xr=min(xr,x[i]+d);
}
if(xr>=xl) return 1;
else return 0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i]>>y[i];
}
double L=0.0,R=INF*1.0;
while(fabs(R-L)>eps){
double mid=(L+R)/2.0;
if(check(mid)){
R=mid;
}else{
L=mid;
}
}
cout<<fixed<<setprecision(15)<<L;
return 0;
}
思路:
三分模板题
最大距离最小,最小的点的左边和右边一定比他大,且这个函数显单调递减后单调递增的趋势,想到三分法。
写个check函数求每次的最大距离比较即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll maxn = 1e5 + 5;
int n;
double x[maxn],y[maxn];
double check(double p){
double res=NINF;
for(int i=1;i<=n;i++){
res=max(res,sqrt((x[i]-p)*(x[i]-p)+y[i]*y[i]));
}
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i]>>y[i];
}
double L=-10000.0,R=10000.0;
while(R-L>eps){
double mid=(R+L)/2;
double midmid=(mid+R)/2;
if(check(mid)<check(midmid))
R=midmid;
else
L=mid;
}
printf("%.5lf",check(R));
return 0;
}