题目描述
It is getting dark and the mosquitoes are attacking Fisherman Floyd. Floyd decides to throw his circular net one last time and wants to make the most out of the last throw.
Given the size (radius) of Floyd’s net and positions (x,y) of a set of fish, what is the maximum fish Floyd can catch with one throw? That is, find the maximum points you can have in the net (circle).
If a point (fish) is within 10 -6 of the circle boundary, consider the point in the circle.
输入
The first input line provides the radius of the circle. The second input line contains an integer, n (1 ≤ n ≤ 100), indicating the number of fish. Each of the next n input lines provides the location (x,y) for one fish. Assume all these points are distinct. Also assume that all the x and y values in
the input (as well as the circle radius) are integers between 1 and 1000, inclusive.
输出
Print the maximum fish Floyd can catch with one throw.
样例输入 Copy
【样例1】
20
4
6 7
5 5
190 100
4 4
【样例2】
3
2
1 1
95 4
样例输出 Copy
【样例1】
3
【样例2】
1
题意
就是给出你一个半径为 R R R的网 给你 N N N个鱼的坐标,然后就是问你在误差允许的范围内,让你求得围住的点数最多。(误差1e-6 )
思路
解决这一问题的思路其实就是先定圆心然后判断其他店是否在圆内就行。
剩下的看下图吧:
这样就可以求得圆点坐标。具体看下代码上的注释吧。
/**遇到此类型的题目就是先确定圆心再去判断其他店是否在圆上或者圆内**/
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
#include <immintrin.h>
#pragma GCC optimize(2)
#include <map>
#include <queue>
#include <string>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <math.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
typedef pair<ll,ll> pii;
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
const int maxn=2e5+1010;
#define inf 0x3f3f3f3f
#define sf scanf
#define pf printf
const int mod=998244353;
const int MOD=10007;
const double eps=1e-6;
inline int read() {
int x=0;
bool t=false;
char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
/*
vector<ll> m1;
vector<ll> m2;
priority_queue<ll , vector<ll> , greater<ll> > mn;//上 小根堆 小到大
priority_queue<ll , vector<ll> , less<ll> > mx;//下 大根堆 大到小
map<ll,ll>mp;*/
ll r,num;
struct Point
{
double x,y;
Point(){}
Point(double tx,double ty){x=tx;y=ty;}
}p[200];
double dist(Point p1,Point p2)
{
return sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2));///求出两点距离
}
Point Center(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(r*r-pow(dist(p1,mid),2));///求出侧边也就是圆心到其中点的距离
return Point(mid.x+d*cos(angle),mid.y+d*sin(angle));///求出圆心坐标
}
int main()
{
cin>>r;
cin>>num;
for(int i=0;i<num;i++)
cin>>p[i].x>>p[i].y;
ll ans = 1;
for(int i=0;i<num;i++)
{
for(int j=i+1;j<num;j++)
{
if(dist(p[i],p[j]) > 2.0*r) continue;///两点距离比直径大直接退出
Point center = Center(p[i],p[j]);///求出圆心的
ll cnt = 0;
for(int k=0;k<num;k++)
if(dist(center,p[k]) < 1.0*r+eps) cnt++;///求这个求出来的圆心点到个点的距离是否瞒住条件
ans = max(ans,cnt);///求出最大值
}
}
cout<<ans<<endl;
return 0;
}