Gone Fishing(计算几何)

该博客讨论了一种算法问题,即渔民弗洛伊德如何使用圆形渔网在允许的误差范围内捕获最多的鱼。给定渔网半径和鱼的位置坐标,目标是找到能捕获最多鱼的圆心。解决方案涉及计算两点间的中点,确定圆心,并检查每个鱼的位置是否在圆内或边界上。通过比较不同圆心捕获的鱼的数量,找出最佳策略。博客中包含了样例输入和输出,以及相应的代码实现,展示了如何通过计算几何来解决此类问题。
摘要由CSDN通过智能技术生成

题目描述
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 个鱼的坐标,然后就是问你在误差允许的范围内,让你求得围住的点数最多。(误差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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值