2020牛客寒假算法基础集训营5.B——牛牛战队的比赛地【三分】

题目传送门


题目描述

由于牛牛战队经常要外出比赛,因此在全国各地建立了很多训练基地,每一个基地都有一个坐标 ( x , y ) (x,y)
这周末,牛牛队又要出去比赛了,各个比赛的赛点都在 x x 轴上。牛牛战队为了方便比赛,想找一个到达训练基地最大距离最小的地方作为比赛地。
这个问题对于牛牛战队太简单了,它就交给了你,你来帮他算一下~


输入描述:

输入数据第一行包含一个整数 N ( 1 N 100 000 ) N(1 \leq N \leq 100\,000) ,表示牛牛战队训练基地的数量。

接下来 N N 行,每行包括 2 2 个整数 x , y ( 10 000 x , y 10 000 ) x,y(-10\,000 \leq x,y \leq 10\,000) ,表示每一个训练基地的坐标。


输出描述:

输出一个小数,表示选择的比赛地距离各训练基地最大距离的最小值。

如果你的答案是 a a ,标准答案是 b b ,当 a b m a x ( 1 , b ) 1 0 4 \frac{|a-b|}{max(1,|b|)}\leq 10^{-4} 时,你的答案将被判定为正确。


输入

3
0 0
2 0
0 2


输出

2


说明

当在 ( 0 , 0 ) (0,0) 比赛时,到三个训练基地的最大距离是 2 2 。可以证明这是最小值。


题解

  • 注意所有点都在 X X 轴上(md,没注意,最开始以为是二维平面的
  • 既然都在 X X 轴上,那么很容易判断,对于函数 f ( x ) = min { max { d i s ( x , i ) } ( i [ 1 , n ] ) } f(x)=\min\{\max\{dis(x,i)\}(i\in[1,n])\} 是一个下凹函数,有最值,那么很显然可以三分处理
  • 注意精度控制,不然会TLE

AC-Code

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 7;
const double eps = 1e-5;
struct Node {
	double x, y;
}a[maxn];
int n;
double check(double x) {
	double max_dis = 0;
	for (int i = 0; i < n; ++i) {
		double t = sqrt(a[i].y * a[i].y + (a[i].x - x) * (a[i].x - x));
		if (t > max_dis)	max_dis = t;
	}
	return max_dis;
}
double search(double low, double high) {
	while (low + eps < high) { // 控制精度,符合题意即可退出
		double mid = (low + high) / 2;
		double midmid = (mid + high) / 2;
		if (check(mid) < check(midmid))
			high = midmid;
		else
			low = mid;
	}
	return check(low);
}
int main() {
	while (cin >> n) {
		for (int i = 0; i < n; ++i)
			cin >> a[i].x >> a[i].y;
		printf("%.5f\n", search(-1e4, 1e4));
	}
	return 0;
}
发布了180 篇原创文章 · 获赞 111 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Q_1849805767/article/details/104301255