给定半径圆心未定的圆和若干点

Pesky Mosquitoes
Time Limit: 4000ms, Special Time Limit:10000ms,Memory Limit:65536KB
Total submit users: 9, Accepted users:9
Problem 13239 : No special judgement
Problem description

Mosquitoes are relentless this time of year! They have absolutely ruined your attempt at a picnic and it is time to take your revenge. Unfortunately, you are not well equipped to ward off these pests. All you have got at your disposal is an empty bowl that previously held potato salad. As you glance down at the picnic table, you see a number of mosquitoes waiting idly for you to let your guard down. This is your chance to fight back.

Your task is to determine the maximum number of mosquitoes that can be trapped by quickly bringing down the inverted bowl onto the table. You will be provided with the diameter of the bowl and the exact location of each mosquito on the table. In this exercise you can assume that the mosquitoes are incredibly small and can simply be modeled as a point. A mosquito that lies exactly under the edge of the bowl is considered trapped.

Input

The first number in the input will be an integer 1 ≤ n ≤ 100 that denotes the number of mosquito- trapping scenarios that follow. A blank line comes at the beginning of each scenario. Then follows a line containing an integer 1 ≤ m ≤ 32 (the number of mosquitoes) and a real number 0 < d ≤ 200 (the diameter of the bowl). Each of the following m lines will specify the location of a mosquito in the form of real coordinates −100 ≤ x ≤ 100 and −100 ≤ y ≤ 100.

Output

For each scenario, you are to print the maximum number of mosquitoes that can be caught under the bowl in that scenario. You may assume that the answer would not change if the diameter of the bowl is increased by at most 10−5.

Sample Input
2
4 1.5
1.0 3.75
3.0 1.0
1.0 2.25
1.5 3.0
8 3.0
-1.0 3.0
-1.0 2.0
-2.0 1.0
0.0 1.0
1.0 0.0
1.0 -1.0
2.0 -2.0
3.0 -1.0
Sample Output
3
4
Problem Source

ACM-ICPC North America Qualifier 2014


一个覆盖最多点的圆,必然至少有两个点在圆上。  枚举两个点,求过这两个点的单位圆,判断有多少个点在圆中,枚举N^2,判断N

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<map>
#include<string>
#include<vector>
#include<set>
#define long long LL
using namespace std;
const double eps=1e-5;
const double PI=acos(-1);
struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){}
};
typedef Point Vector;
Vector operator +(Vector A,Vector B)
{
    return Vector(A.x+B.x,A.y+B.y);
}
Vector operator -(Vector A,Vector B)
{
    return Vector(A.x-B.x,A.y-B.y);
}
Vector operator *(Vector A,double p)
{
    return Vector(A.x*p,A.y*p);
}
Vector operator /(Vector A,double p)
{
    return Vector(A.x/p,A.y/p);
}
bool operator <(const Point& a,const Point& b)
{
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int dcmp(double x)
{
    if(fabs(x)<eps)
        return 0;
    else
        return x<0?-1:1;
}
bool operator ==(const Point& a,const Point& b)
{
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Dot(Vector A,Vector B)
{
    return A.x*B.x+A.y*B.y;
}
double Length(Vector A)
{
    return sqrt(Dot(A,A));
}


Vector Normal(Vector A)
{
    double L=Length(A);
    return Vector(-A.y/L,A.x/L);
}
double angle(Vector v)
{
    return atan2(v.y,v.x);
}
double r;
Point Get_circleCenter(Point p1,Point p2)
{
    Vector p=p2-p1;
    Point mid=(p1+p2)/2;
    double d=sqrt(r*r/4-Length(mid-p1)*Length(mid-p1));
    double rad=angle(Normal(p2-p1));
    return Point(mid.x+d*cos(rad),mid.y+d*sin(rad));
}
int main()
{
    int kase;
    cin>>kase;
    while(kase--)
    {
        int m;
        cin>>m;
        cin>>r;
        Point mo[40];
        for(int i=0;i<m;i++)
            cin>>mo[i].x>>mo[i].y;
        int ans=1;
        for(int i=0;i<m;i++)
            for(int j=i+1;j<m;j++)
        {
            if(Length(mo[i]-mo[j])>r)
                continue;
            Point center=Get_circleCenter(mo[i],mo[j]);
            int cnt=0;
            for(int k=0;k<m;k++)
                if(Length(center-mo[k])<r/2+1e-5) cnt++;
            ans=max(ans,cnt);
        }
        cout<<ans<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值