知乎上有这个问题 比赛的时候实现了算法 调了整场啊... 知乎链接
按照这位大佬的代码 取大于的所有区间终于过了 这里
然而我的把角度全部映射到-pi~pi的算法怎样也过不了
Node的排序方法也是玄学 不要优先+1反而ac 优先+1反而wa
总之就是把下面代码的注释全部去了差不多就是我的错误代码了。。求好心的大佬帮忙看一下。。
附上这个被改成长得跟别人差不多的ac代码。。。
#include <iostream>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <algorithm>
using namespace std;
const double eps=1e-6;
const double pi=acos(-1.0);
int sgn(double x)
{
if(fabs(x)<eps)return 0;
return x>eps?1:-1;
}
struct Point {
double x, y;
Point() {}
Point(double _x, double _y) {
x = _x;
y = _y;
}
void input() {
scanf("%lf%lf", &x, &y);
}
void output() {
printf("%.2f %.2f\n", x, y);
}
bool operator==(Point b) const {
return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
}
bool operator<(Point b) const {
return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;
}
Point operator-(const Point &b) const {
return Point(x - b.x, y - b.y);
}
//叉积
double operator^(const Point &b) const {
return x * b.y - y * b.x;
}
//点积
double operator*(const Point &b) const {
return x * b.x + y * b.y;
}
double distance(Point p) {
return hypot(x - p.x, y - p.y);
}
Point operator+(const Point &b) const {
return Point(x + b.x, y + b.y);
}
Point operator*(const double &k) const {
return Point(x * k, y * k);
}
Point operator/(const double &k) const {
return Point(x / k, y / k);
}
};
struct Node{
int f;
double a;
Node(double _a,int _f){f=_f;a=_a;}
Node(){}
bool operator<(const Node&b)const{
// if(sgn(a-b.a)==0)return f>b.f;
return a<b.a;
}
}g[10000];
double get(double x)
{
while(sgn(x+pi)<0)x+=2*pi;
while(sgn(x-pi)>0)x-=2*pi;
return x;
}
void add(double a,double b,int &cnt)
{
// a=get(a);
// b=get(b);
a+=2*pi;
b+=2*pi;
g[cnt]=Node(a,1);cnt++;
g[cnt]=Node(b,-1);cnt++;
// if(sgn(a-b)>0)
// {
// g[cnt]=Node(-pi,1);cnt++;
// g[cnt]=Node(pi,-1);cnt++;
// }
}
void fuck(Point p1,Point p2,int &cnt,double R)
{
double d=p1.distance(p2);
if(d>R*2)return;
// if(sgn(d)==0)///重合
// {
// add(-pi,pi,cnt);
// }
// else if(sgn(d-R*2)==0)///相切
// {
// double t=acos((p2.x-p1.x)/d);
// add(t,t,cnt);
// }
// else///相交
{
double A=acos(0.5*d/R);
// double B=acos((p2-p1).x/d);
double B=atan2((p2-p1).y,(p2-p1).x);
if(B<0)B+=2*pi;
// if(!flag)
// add(B+A,B-A,cnt);
// else
add(B-A,B+A,cnt);
}
}
Point p[100000];
int main()
{
double R;
int n,T,s,rr;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&s);
for(int i=0;i<n;i++)
{
p[i].input();
}
R=0;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
R=max(R,p[i].distance(p[j]));
}
}
scanf("%d",&rr);
if(s>n)
{
printf("The cake is a lie.\n");
continue;
}
if(s==1)
{
printf("%d.0000\n",rr);
continue;
}
double ri=R;
double le=0;
int mx;
while(ri-le>eps)
{
mx=0;
double mid=0.5*(le+ri);
int flag=0;
for(int i=0;i<n;i++)
{
int cnt=0;
for(int j=0;j<n;j++)
{
if(i==j)continue;
fuck(p[i],p[j],cnt,mid);
}
sort(g,g+cnt);
int ss=1;
for(int j=0;j<cnt;j++)
{
ss+=g[j].f;
mx=max(ss,mx);
if(ss>=s)
{
flag=1;
break;
}
}
if(flag)break;
}
if(flag) ri=mid;
else le=mid;
}
le+=rr;
printf("%.4f\n",le);
}
return 0;
}
/*
2
3 3
0 0
1 1
2 0
1
3 3
0 0
1 1
2 2
1
*/