https://ac.nowcoder.com/acm/contest/7830/D
感觉沈阳的惨败都是上个世纪的事情了。。。刚好牛客国庆集训3把沈阳的题放出来了,拿出来补补,就是个圆的反演水题,当时很多队很早就过了,然而最后也就那么多人过,因为2018-2019年的各种比赛题目中没出现过
这题就拿(0,0),半径为2*R当反演圆,然后两个过切点的圆反演过去就是两条直线,吧所有点反演过去就是直线之间的点,因为望远镜的区域跟原来的大圆小圆相切并夹在中间,反演过去就也是夹在中间相切的,半径就知道了,横坐标也是确定的
然后我们可以求出每个点包含他的圆的圆心的纵坐标的范围,因为不能在边界上,所以规定一下左闭右开,按l排序,然后用个堆或者multiset每次找出最小的丢进去的r看要不要弹出就行了
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8;
inline int sgn(double x)
{
if(fabs(x)<eps) return 0;
if(x<0) return -1;
else return 1;
}
inline double mysqrt(double x)
{
return sqrt(max(x,0.0));
}
struct point
{
double x,y;
point(double a=0,double b=0)
{
x=a;y=b;
}
point operator + (const point &b)const
{
return point(x+b.x,y+b.y);
}
point operator - (const point &b)const
{
return point(x-b.x,y-b.y);
}
friend point operator * (const point &p,double t)
{
return point(t*p.x,t*p.y);
}
double norm()
{
return mysqrt(x*x+y*y);
}
};
struct circle
{
point o;double r;
circle(point a=point(0,0),double R=0)
{
o=a;r=R;
}
};
const int maxl=1e4+10;
int n,tot,ans;
point a[maxl],b[maxl];
double r,R,lb,rb;
circle c;
struct seg
{
double l,r;
}se[maxl];
priority_queue<double,vector<double>,greater<double> >q;
inline point inverse_point(point p,circle a)
{
point res;
double len=(p-a.o).norm();
double len2=a.r*a.r/len;
res=a.o+(p-a.o)*(len2/len);
return res;
}
inline void prework()
{
scanf("%d",&n);
scanf("%lf%lf",&R,&r);
c.o=point(0,0);c.r=2*R;
lb=2*R;rb=2*R*2*R/(2*r);
double dx,dy,dr=(rb-lb)/2;
tot=0;
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&a[i].x,&a[i].y);
b[i]=inverse_point(a[i],c);
dx=fabs(b[i].x-((lb+rb)/2));
dy=mysqrt(dr*dr-dx*dx);
se[i]=seg{b[i].y-dy,b[i].y+dy};
}
}
inline bool cmp(const seg &a,const seg&b)
{
if(sgn(a.l-b.l)==0)
return a.r<b.r;
return a.l<b.l;
}
inline void mainwork()
{
int num=0;ans=0;
sort(se+1,se+1+n,cmp);
while(!q.empty())
q.pop();
for(int i=1;i<=n;i++)
{
q.push(se[i].r);num++;
while(q.top()<se[i].l+eps)
{
num--;
q.pop();
}
ans=max(ans,num);
}
}
inline void print()
{
printf("%d\n",ans);
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}