2018 沈阳网络赛E The cake is a lie(最大圆覆盖)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37632935/article/details/82534330

完全是个板子题,二分半径套一个套一个最大圆覆盖的板子即可。

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

#define Mn 305
const double eps = 1e-7;
const double pi = acos(-1.0);
#define sqr(x) ((x) * (x))
struct Point
{
	double x,y;
	Point() {}
	Point(double tx,double ty)
	{
		x=tx;
		y=ty;
	}
} p[Mn+5];
struct Node
{
	double angle;
	bool in;
} arc[Mn * Mn + 5];
int n,cnt;
double dist(Point p1,Point p2)
{
	return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
bool cmp(Node &n1,Node &n2)
{
	return n1.angle<n2.angle;
}
double R;

int MaxCircleCover()
{
    int ans=1;
    for(int i=0;i<n;i++)
	{
        int cnt=0;
        for(int j=0;j<n;j++)
		{
            if(i==j) continue;
            double D = dist(p[i],p[j]);
            if(D>2.0*R) continue;
            
            double angle=atan2(p[i].y-p[j].y,p[i].x-p[j].x);
            if(angle < 0)
                angle += 2 * pi;
                
            double phi=acos(D/(2.0*R));
            arc[cnt].angle=angle-phi+ 2 * pi;arc[cnt++].in=true;
            arc[cnt].angle=angle+phi+ 2 * pi;arc[cnt++].in=false;
        }
        sort(arc,arc+cnt,cmp);
        int tmp=1;
        for(int j=0;j<cnt;j++)
		{
            if(arc[j].in)  tmp++;
            else tmp--;
            ans=max(ans,tmp);
        }
    }
    return ans;
}

int main()
{
	int t;scanf("%d",&t);
	while(t--)
	{
		int s;
		scanf("%d%d",&n,&s);
		for(int i=0;i<n;i++)
			scanf("%lf%lf",&p[i].x,&p[i].y);
		double r;
		scanf("%lf",&r);
		double l1=0,r1=1000000000;
		if(n<s)
		{
			printf("The cake is a lie.\n");continue;
		}
		while(abs(r1-l1)>eps)
		{
			double mid=(l1+r1)*0.5;
			R=mid;
			int p=MaxCircleCover();
			if(p>=s)
			{
				r1=mid;
			}
			else
			{
				l1=mid;
			}
		}
		printf("%.4lf\n",l1+r);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37632935/article/details/82534330