ZOJ 3575 Under Attack III

Under Attack III

Time Limit: 7 Seconds      Memory Limit: 65536 KB

Due to the successful resist in Under Attack II, the enemy lost most of their bombers and our ground forces are advancing for victory. However, our spy has transmitted a shocking intel saying that the insane and desparate enemy set up a crazy plan aiming at our civilians. They will launch nuclear missles to attack prosperous cities in our country ! Doctor has received order from central command to calculate how many cities will be destroyed if the enemy bomber succeed (though the possibility is very little).

According to intel, every nuclear missle has a effect range. The missle's effect range is a ellipse with axis length a parrelling to x axis, axis length b parrelling to y axis.Notice enemy can attack every point. Our spies have got data of the ellipse of missle and now given the cooridinate of cities, please show how many cities will be attacked at most.

Input

The input consists of multiple cases.
The first line are the length a and b of effect ellipse's axises. a b are both in the range of [0,400].a b are both positive floating numbers.
Next line is city number n.n can be up to 200.
Following n lines are x and y non-negative floating numbers cooridinate of each city.
Cities on the edge of ellipse are also regarded as attacked. It's guaranteed that no two cities are at one point.

Output

Output the cities affected at most.

Sample Input
2 3
2
1 1
2 2
Sample Output
2


题意:告诉一个椭圆的长短轴a,b值,以及n个点,求这个椭圆最多能圈住多少个点。

思路:椭圆的话不好处理,所以转化成圆上问题了,把椭圆方程稍微变换一下。然后枚举圆心,至于怎么枚举,其实只要有两个点,就能确定一个圆啊(其实是两个圆)。然后每次枚举看看哪个情况下圈的最多。注意一点就是,可能点与点之间都隔得很开,不存在同时圈住大于等于2个点的情况,这个时候就要输出1.


#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#define eps 1e-6
#define Pi acos(-1.0)
using namespace std;

struct Node
{
    double x,y;
}f[500];

double a,b;
int n;

double dis(double a,double b,double c,double d)
{
    return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}

int solve(double a,double b,double r)
{
    int num=0;

    for(int i=0;i<n;i++)
    {
        if(dis(f[i].x,f[i].y,a,b)-r<eps)
            num++;
    }

    return num;
}

int main()
{
    while(~scanf("%lf%lf",&a,&b))
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf",&f[i].x,&f[i].y);
            f[i].y*=(a/b);//把椭圆上的点转移到圆上
        }
        double r;
        r=a;

        int ans=0;
        int tmp;

        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                double len=dis(f[i].x,f[i].y,f[j].x,f[j].y);
                if(len>2*r) continue;
                len/=2;

                double d=sqrt(r*r-len*len);

                double xx,yy;//求中点
                xx=(f[i].x+f[j].x)/2;
                yy=(f[i].y+f[j].y)/2;

                double aa;

                if(f[i].x-f[j].x==0) aa=Pi/2;
                else aa=atan( (f[j].y-f[i].y)/(f[j].x-f[i].x) );

                aa-=Pi/2;

                double x0,y0;//求 圆心
                x0=xx+d*cos(aa);
                y0=yy+d*sin(aa);

                tmp=solve(x0,y0,r);
                ans=max(ans,tmp);

                x0=xx-d*cos(aa);
                y0=yy-d*sin(aa);

                tmp=solve(x0,y0,r);
                ans=max(ans,tmp);

            }
        }
        
        if(ans==0) ans=1;//如果初始化是1,就不用判断。

        printf("%d\n",ans);

    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值