//对于任意一点已经覆盖了一些点的圆,都可以通过对圆进行偏移,以使其在保证已覆盖的点的基础上,覆盖更多的点 //对这偏移进行到极限,就是刚好使两点在圆上 //其实这题的思路和POJ1106是差不多的,只不过在看到聚会范围在[0,10]的时候想到随机算法去了 //还有一种n^2logn的做法,学习了一下圆上弧被覆盖次数的标记 #include<stdio.h> #include<algorithm> #include<math.h> using namespace std; const double eps=1e-8; struct Point { double x,y; }; struct Node{ double angle; int in; }; Node arc[1005]; Point p[305]; double dist(Point p,Point q){ return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y)); } int cmp(Node a,Node b){ if(a.angle!=b.angle) return a.angle<b.angle; else return a.in>b.in; } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif // ONLINE_JUDGE int n; while(scanf("%d",&n),n){ int ans=1; for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); for(int i=0;i<n;i++){ int cnt=0; for(int j=0;j<n;j++){ if(i==j) continue; if(dist(p[i],p[j])>2.0+eps) continue; double b=atan2(p[j].y-p[i].y,p[j].x-p[i].x); double a=acos(dist(p[i],p[j])/2); arc[cnt].angle=b-a; arc[cnt++].in=1; //把角度小的点作为入点 arc[cnt].angle=b+a; arc[cnt++].in=-1; } sort(arc,arc+cnt,cmp); int tmp=1; for(int j=0;j<cnt;j++){ //if(arc[j].in) tmp++;值为负时if也成立(只要非0都成立) tmp+=arc[j].in; ans=max(ans,tmp); } } printf("%d\n",ans); } return 0; }
时间: 2024-10-29 07:32:50