POJ 1981 定长圆覆盖最多点
题意:
一些点,求一个单位圆最多能覆盖的点的个数,不存在两点距离恰好为2.
题解:
暴力枚举两个点,求圆心,然后枚举每个点验证是否在圆内。n^3的,可以过~
当然还有n^2logn的转化为求圆的最大弧的覆盖次数问题(以后做CIRU 的时候也会用到这个技术~)
n^3
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 8 #define N 333 9 #define EPS 1e-7 10 #define PI 3.141592653589793238 11 #define INF 1e10 12 13 using namespace std; 14 15 struct PO 16 { 17 double x,y; 18 void prt() {printf("%lf %lf\n",x,y);} 19 }p[N]; 20 21 int n,ans; 22 23 const double r=1.0; 24 25 inline void read() 26 { 27 for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); 28 } 29 30 inline PO operator +(PO a,PO b) 31 { 32 PO c; 33 c.x=a.x+b.x; c.y=a.y+b.y; 34 return c; 35 } 36 37 inline PO operator -(PO a,PO b) 38 { 39 PO c; 40 c.x=a.x-b.x; c.y=a.y-b.y; 41 return c; 42 } 43 44 inline int dc(double x) 45 { 46 if(x>EPS) return 1; 47 else if(x<-EPS) return -1; 48 return 0; 49 } 50 51 inline double getdis2(PO &a,PO &b) 52 { 53 return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); 54 } 55 56 inline double getlen(PO &a) 57 { 58 return sqrt(a.x*a.x+a.y*a.y); 59 } 60 61 inline PO rotate(PO a) 62 { 63 PO ans; 64 ans.x=a.y; 65 ans.y=-a.x; 66 return ans; 67 } 68 69 inline PO geto(PO &a,PO &b) 70 { 71 PO mid=a+b; 72 mid.x/=2; mid.y/=2; 73 PO ab=b-a; 74 double len=getlen(ab); 75 ab.x/=len; ab.y/=len; 76 ab=rotate(ab); 77 len=sqrt(r-len*len*0.25); 78 ab.x*=len; ab.y*=len; 79 return mid+ab; 80 } 81 82 inline void check(PO &o) 83 { 84 int res=0; 85 for(int i=1;i<=n;i++) 86 if(dc(getdis2(p[i],o)-r)<=0) res++; 87 ans=max(res,ans); 88 } 89 90 inline void go() 91 { 92 ans=1;PO o; 93 for(int i=1;i<=n;i++) 94 for(int j=i+1;j<=n;j++) 95 if(dc(getdis2(p[i],p[j])-4*r)<=0) 96 { 97 o=geto(p[i],p[j]); 98 check(o); 99 o=geto(p[j],p[i]); 100 check(o); 101 } 102 printf("%d\n",ans); 103 } 104 105 int main() 106 { 107 while(scanf("%d",&n),n) read(),go(); 108 return 0; 109 }
n^2logn
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstring> 3 #include <cmath> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <algorithm> 7 8 #define N 777 9 #define PI 3.141592653589 10 #define EPS 1e-7 11 12 using namespace std; 13 //定长圆覆盖最多点,转为最大弧覆盖次数 14 struct C 15 { 16 double x,y,r; 17 void prt() {printf("%lf %lf\n",x,y);} 18 }c[N]; 19 20 struct T 21 { 22 int fg; 23 double ag; 24 void prt() {printf("%lf %d\n",ag,fg);} 25 }t[N<<2]; 26 27 int n,cnt,ans; 28 double ccd,r=1.0; 29 30 inline int dc(double x) 31 { 32 if(x>EPS) return 1; 33 else if(x<-EPS) return -1; 34 return 0; 35 } 36 37 inline C operator +(C a,C b) 38 { 39 C tmp; 40 tmp.x=a.x+b.x; tmp.y=a.y+b.y; 41 return tmp; 42 } 43 44 inline C operator -(C a,C b) 45 { 46 C tmp; 47 tmp.x=a.x-b.x; tmp.y=a.y-b.y; 48 return tmp; 49 } 50 51 inline C operator *(C a,double k) 52 { 53 a.x*=k; a.y*=k; 54 return a; 55 } 56 57 inline C operator /(C a,double k) 58 { 59 a.x/=k; a.y/=k; 60 return a; 61 } 62 63 inline void read() 64 { 65 for(int i=1;i<=n;i++) 66 { 67 scanf("%lf%lf",&c[i].x,&c[i].y); 68 c[i].r=1.0; 69 } 70 } 71 72 inline bool cmp(const T &a,const T &b) 73 { 74 if(dc(a.ag-b.ag)==0) return a.fg>b.fg; 75 return a.ag<b.ag; 76 } 77 78 inline double getdis(const C &a,const C &b) 79 { 80 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 81 } 82 83 inline C getf(const C &a,const C &b)//单位法向量 84 { 85 C tmp=b-a; tmp=tmp/ccd; 86 C ans; 87 ans.x=-tmp.y; ans.y=tmp.x; 88 return ans; 89 } 90 91 inline void getcpoint(const C &c1,const C c2,C &a,C &b) 92 { 93 double cs=(c2.r*c2.r+ccd*ccd-c1.r*c1.r)/(2*ccd); 94 double cp=ccd-cs; 95 double hh=sqrt(c1.r*c1.r-cp*cp); 96 C f=getf(c1,c2); 97 f=f*hh; 98 a=((c2-c1)*cp/ccd-f); 99 b=((c2-c1)*cp/ccd+f); 100 } 101 102 inline void go() 103 { 104 ans=0; 105 C o1,o2; 106 for(int i=1;i<=n;i++) 107 { 108 cnt=0; 109 for(int j=1;j<=n;j++) 110 { 111 if(i==j) continue; 112 ccd=getdis(c[i],c[j]); 113 if(dc(ccd-2*r)>0) continue; 114 getcpoint(c[i],c[j],o1,o2); 115 double ag1=atan2(o1.y,o1.x); 116 double ag2=atan2(o2.y,o2.x); 117 if(dc(ag1)>0&&dc(ag2)<=0)//跨越x轴负半轴,拆开 118 { 119 t[++cnt].fg=1; t[cnt].ag=ag1; 120 t[++cnt].fg=-1; t[cnt].ag=PI; 121 t[++cnt].fg=1; t[cnt].ag=-PI; 122 t[++cnt].fg=-1; t[cnt].ag=ag2; 123 } 124 else 125 { 126 t[++cnt].fg=1; t[cnt].ag=ag1; 127 t[++cnt].fg=-1; t[cnt].ag=ag2; 128 } 129 } 130 sort(t+1,t+1+cnt,cmp); 131 int res=0; 132 for(int j=1;j<=cnt;j++) 133 { 134 res+=t[j].fg; 135 ans=max(ans,res); 136 } 137 } 138 printf("%d\n",ans+1); 139 } 140 141 int main() 142 { 143 while(scanf("%d",&n),n) read(),go(); 144 return 0; 145 }
没有人能阻止我前进的步伐,除了我自己!