牛牛战队的比赛地——三分
链接:https://ac.nowcoder.com/acm/contest/3006/B
来源:牛客网
题目描述
由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标(x,y)(x,y)(x,y)。
这周末,牛牛队又要出去比赛了,各个比赛的赛点都在xxx轴上。牛牛战队为了方便比赛,想找一个到达训练基地最大距离最小的地方作为比赛地。
这个问题对于牛牛战队太简单了,它就交给了你,你来帮他算一下~
输入描述:
输入数据第一行包含一个整数N(1≤N≤100 000)N(1 \leq N \leq 100\,000)N(1≤N≤100000),表示牛牛战队训练基地的数量。
接下来NNN行,每行包括222个整数x,y(−10 000≤x,y≤10 000)x,y(-10\,000 \leq x,y \leq 10\,000)x,y(−10000≤x,y≤10000),表示每一个训练基地的坐标。
输出描述:
输出一个小数,表示选择的比赛地距离各训练基地最大距离的最小值。
如果你的答案是aaa,标准答案是bbb,当∣a−b∣max(1,∣b∣)≤10−4\frac{|a-b|}{max(1,|b|)}\leq 10^{-4}max(1,∣b∣)∣a−b∣≤10−4时,你的答案将被判定为正确。
示例1
输入
3 0 0 2 0 0 2
输出
2
说明
当在(0,0)(0,0)(0,0)比赛时,到三个训练基地的最大距离是222。可以证明这是最小值。
题目思路:题目要求最大距离最小,很容易想到使用二分或者三分的方法去做。
这题使用三分会比较简单,二分会比较麻烦。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 struct p{ 5 int x,y; 6 }a[100005]; 7 int n; 8 double check(double x) 9 { 10 double max=0; 11 for (int i=1;i<=n;i++) 12 { 13 double tmp=sqrt(a[i].y*a[i].y+(a[i].x-x)*(a[i].x-x)); 14 if (tmp>max) max=tmp; 15 } 16 return max; 17 } 18 double tsearch(double left,double right){ 19 int i; 20 double mid,midmid; 21 for(i=0;i<100;i++){ 22 mid=left+(right-left)/2; 23 midmid=mid+(right-mid)/2; 24 if(check(mid)>check(midmid)) //极大值求法 25 left=mid; 26 else 27 right=midmid; 28 } 29 return mid; 30 } 31 int main() 32 { 33 scanf("%d",&n); 34 for (int i=1;i<=n;i++) 35 scanf("%d%d",&a[i].x,&a[i].y); 36 double max=tsearch(-10000,10000); 37 printf("%.4lf\n",check(max)); 38 return 0; 39 }