版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}