# POJ 1981 Circle and Points(单位圆覆盖n^3&&n^2lgn)

25 篇文章 0 订阅

http://poj.org/problem?id=1981

N^3做法。一个覆盖最多点的圆，必然至少有两个点在圆上。当然n>=2而且结果大于2

#include<iostream>
#include<fstream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<sstream>
#include<ctime>
#include<cassert>
#define LL long long
#define eps 1e-8
#define inf 999999.0
#define zero(a) abs(a)<eps
#define N 20
#define MOD 100000007
#define pi acos(-1.0)
using namespace std;
struct Point{
double x,y;
Point(){}
Point(double tx,double ty){x=tx;y=ty;}
}p[300];
int n;
double dist(Point p1,Point p2){
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
Point get_circle(Point p1,Point p2){
Point mid=Point((p1.x+p2.x)/2,(p1.y+p2.y)/2);
double angle=atan2(p1.x-p2.x,p2.y-p1.y);
double d=sqrt(1-dist(p1,mid)*dist(p1,mid));
return Point(mid.x+d*cos(angle),mid.y+d*sin(angle));
}
int main(){
while(scanf("%d",&n)!=EOF&&n){
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
int ans=1;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(dist(p[i],p[j])>2.0) continue;
Point central=get_circle(p[i],p[j]);
int cnt=0;
//    printf("%.6f %.6f\n",dist(p[i],central),dist(p[j],central));
for(int k=0;k<n;k++)
if(dist(central,p[k])<1.0+eps)
cnt++;
ans=max(ans,cnt);
}
}
printf("%d\n",ans);
}
return 0;
}

N^2lgN做法。以每一个点扩展成单位圆，那么两两之间可能会有相交，形成相交弧。

#include<iostream>
#include<fstream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<sstream>
#include<ctime>
#include<cassert>
#define LL long long
#define eps 1e-8
#define inf 999999.0
#define zero(a) abs(a)<eps
#define N 20
#define MOD 100000007
#define pi acos(-1.0)
using namespace std;
struct Point{
double x,y;
Point(){}
Point(double tx,double ty){x=tx;y=ty;}
}p[300];
struct Node{
double angle;
bool in;
}arc[180000];
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?n1.angle<n2.angle:n1.in>n2.in;
}
void 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;
if(dist(p[i],p[j])>2.0) continue;
double angle=atan2(p[i].y-p[j].y,p[i].x-p[j].x);
double phi=acos(dist(p[i],p[j])/2);
arc[cnt].angle=angle-phi;arc[cnt++].in=true;
arc[cnt].angle=angle+phi;arc[cnt++].in=false;
}
sort(arc,arc+cnt,cmp);
int tmp=1;
for(int i=0;i<cnt;i++){
if(arc[i].in)  tmp++;
else tmp--;
ans=max(ans,tmp);
}
}
printf("%d\n",ans);
}
int main(){
while(scanf("%d",&n)!=EOF&&n){
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
MaxCircleCover();
}
return 0;
}


07-09 915
07-08 6654

08-31 99
04-08 512
02-25 342
11-25 241
05-08 174
09-18 2701
09-04 1695
05-03 1350
04-08 1111
09-12 3727

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

ACM_cxlove

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。