• A 签到
  • B
    • 题意:在x轴上找一个点,使得它到给定的点之间的最大距离最小,输出最大距离的最小值
    • 思路:答案点的左/右侧,得到的最大距离都比答案大,所以答案所在的点是一个极小值点。可以对在x轴上找的这个点三分,或者对最大距离二分,找到第一个满足答案的最大距离(该距离最小)
    • ac代码:
//三分法
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
struct node{int x, y;
}a[maxn];
int n;
double maxdis(double x)
{double ans = 0;for(int i = 1; i <= n; i++)ans = max(ans, sqrt(a[i].y*a[i].y+(a[i].x-x)*(a[i].x-x)));return ans;
}
int main()
{//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);scanf("%d", &n);for(int i = 1; i <= n; i++) scanf("%d %d", &a[i].x, &a[i].y);double l = -10000, r = 10000;while((r-l)>1e-7){double midl = (r+l)/2;double midr = (midl+r)/2;if(maxdis(midl)>=maxdis(midr)) l = midl;else r = midr;}printf("%.6f\n", maxdis(r));return 0;
}
//二分
#include<bits/stdc++.h>
#define lowbit(x) ((x)&(-(x)))
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
int n;
double x[maxn],y[maxn];
bool check(double r)
{double low=-1e10,up=1e10;for(int i=1;i<=n;i++){if(abs(y[i])>r)return false;double s=x[i]-sqrt(r*r-y[i]*y[i]),t=x[i]+sqrt(r*r-y[i]*y[i]);if(t<low||s>up)return false;if(t<up)up=t;if(s>low)low=s;}return true;
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%lf %lf",&x[i],&y[i]);double L=0,R=10000*sqrt(2)+10;while((R-L)>1e-7){double MID=(R+L)/2;if(check(MID))R=MID;elseL=MID;}printf("%.7f\n",L);return 0;
}