//对于任意一点已经覆盖了一些点的圆,都可以通过对圆进行偏移,以使其在保证已覆盖的点的基础上,覆盖更多的点
//对这偏移进行到极限,就是刚好使两点在圆上
//其实这题的思路和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;
}
原文地址:http://blog.csdn.net/lj94093/article/details/44132109