[zoj]3575 Under Attack III
题目大意:
给出一个椭圆和平面上的一些点,求椭圆最多覆盖的点数。其中椭圆长短轴方向固定不可旋转。
思路:
首先将图的横纵坐标乘上一定系数使椭圆覆盖问题变为圆覆盖问题。可以很容易地证明,一定存在一个最优解使得圆周上存在两个或两个以上地点。
由于圆的半径一定,所以枚举圆周上的两个点,可算出圆的位置(可能有两个不同的圆),再求出覆盖点数并取最优解。
#include <stdio.h>
#include "stdlib.h"
#include "math.h"
double dis(double x1,double y1,double x2,double y2){
return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
long try(double p[210][2],long n,double xo,double yo,double r){
double d;
long i,re;
re=0;
for (i=0;i<n;i++){
d=dis(p[i][0], p[i][1], xo, yo);
if ((d-r)<0.0001){
re+=1;
}
}
return re;
}
int main (){
double p[210][2],a,b,x,y,x1,y1,x2,y2,xp,yp,r,d,an,pi,xo,yo;
long i,j,k,n,max,te;
pi=asin(1);
while (scanf("%lf%lf",&a,&b)!=EOF){
a=a*2;
b=b*2;
scanf("%ld",&n);
for (i=0;i<n;i++){
scanf("%lf%lf",p[i],p[i]+1);
p[i][1]*=(a/b);
}
r=a/2;
max=0;
for (i=0;i<n;i++){
for (j=i+1;j<n;j++){
d=dis(p[i][0],p[i][1],p[j][0],p[j][1]);
if (d>a)
continue;
xp=sqrt(r*r-d*d/4);
an=atan((p[j][1]-p[i][1])/(p[j][0]-p[i][0]))-pi;
yp=xp*sin(an);
xp=xp*cos(an);
xo=(p[i][0]+p[j][0])/2;
yo=(p[i][1]+p[j][1])/2;
te=try(p,n,xo+xp,yo+yp,r);
if (te>max)
max=te;
te=try(p,n,xo-xp,yo-yp,r);
if (te>max)
max=te;
}
}
if (max==0)
max=1;
printf("%ld\n",max);
}
return 0;
}

浙公网安备 33010602011771号