codeforces 1059 D. Nature Reserve(几何+二分)

题目:http://codeforces.com/contest/1059/problem/D

题意:给出n个点,要求做一个圆,使得所有点在圆内或圆上,并且该圆与x轴相切。

思路:与y轴相切,那么圆心位置一定在(x,r)上,这道题不需要我们确定圆心位置,那么反着思考,如果该圆包含所有点,那么其他所有点以r作半径的圆一定包含该圆点,然后圆心又在 y=r 这条直线上,我们就可以通过每个点作的圆与这条线交的范围是否存在,判断是否存在这样的圆,r可以用二分查找 时间复杂度(nlog(max))

要注意一下精度,这里用long double 或者勾股定理时先开根号比较稳…

#include<bits/stdc++.h>
#define fi first
#define se second
#define log2(a) log(n)/log(2)
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const ll inf = 1e17 + 10;
const int N = 1e6 + 10;
const ll mod = 1e9+7;
const int base=131;
const double pi=acos(-1);
map<string, int>ml;


map<ll,ll> mp;
map<int,int> vi;
priority_queue<P> q;
priority_queue<P> tq;



ll b[N], vis[N], dep[N],num[N], a[N],t, n, m,  k;
int ex, ey, cnt, ans, sum, flag;
double x[N],y[N],po[N];
//vector<int> v[N];
vector<int> fac[N];
string s;
map<int,int> dp[N];

char v[1005][1005];

bool check(double R)
{
	double l=-1e18,r=1e18,t;
	for(int i=1;i<=n;i++)
	{
		if(y[i]>2*R) return 0;
		t=sqrt(R+(R-y[i]))*sqrt(R-(R-y[i]));
		l=max(l,x[i]-t);
		r=min(r,x[i]+t);
	}
	return l<=r;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>x[i]>>y[i];
		if(y[i]>0) vis[1]=1;
		if(y[i]<0) vis[0]=1;
	}
	if(vis[1]&&vis[0]) return cout<<-1,0;
	if(vis[0])
	{
		for(int i=1;i<=n;i++) y[i]=-y[i];
	}
	double  l=0,r=1e18,ans,mid;
	for(int i=1;i<=500;i++)
	{
		mid=(l+r)/2.0;
		if(check(mid))
		{
			ans=r=mid;
		}
		else l=mid;
	}
	printf("%.10f",ans);


}

猜你喜欢

转载自blog.csdn.net/weixin_42640692/article/details/88179959