sicily 4834. Party Location

已知在平面上有若干个点,求一个已知半径的圆最多更覆盖多少个点。

一个比较经典的问题。(另一个为已知若干个点,求能覆盖住所有点的圆的最小半径。)

两两点枚举,分别以两点为圆心,已知半径画圆,若相交,则求出两圆的一个交点(两边可任意,但是每两个圆的交点都要取同一边的),然后判断以交点为圆心已知半径为半径的圆能覆盖多少个点(在圆上也算)。逐个更新ans,直到枚举完全,最后ans的值即为能覆盖住的点的最大个数。

 

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

struct point
{
	double x, y;
};

double dis(point p1, point p2)        //两点间距离平方
{
	point p3;
	p3.x = p2.x - p1.x;
	p3.y = p2.y - p1.y;
	return p3.x * p3.x + p3.y * p3.y;
}

point find_centre(point p1, point p2)      //找到固定半径圆的圆心位置,圆心均应找在连线的同一边
{
	point p3, mid, centre;
	double b, c, ang;
	p3.x = p2.x - p1.x;
	p3.y = p2.y - p1.y;
	mid.x = (p1.x + p2.x) / 2;
	mid.y = (p1.y + p2.y) / 2;
	b = dis(p1, mid);
	c = sqrt(6.25 - b);
	if(fabs(p3.y) < 0.000001)   //两圆心连线的垂线的斜角90度
	{
		centre.x = mid.x;
		centre.y = mid.y + c;
	}
	else
	{
		ang = atan(-p3.x / p3.y);
		centre.x = mid.x + c * cos(ang);
		centre.y = mid.y + c * sin(ang);
	}
	return centre;
}

int main()
{
    int n, ans, tmpans, i, j, k;
    point p[205], centre;
    double tmp;
	n=0;
    while(scanf("%lf%lf", &p[n].x, &p[n].y)!=EOF )
    {
		n++;
	}
	ans = 1;
	for(i = 0;i < n;i++)        //两两圆枚举所有情况
		for(j = i + 1;j < n;j++)
		{
			if(dis(p[i], p[j]) >25) continue;   //当以这两个点为圆心画的圆不相交时直接跳过
			tmpans = 0;
			centre = find_centre(p[i], p[j]);
			for(k = 0;k < n;k++)      //判断以新圆心为圆心时的圆覆盖住的点的个数
			{
				tmp = dis(centre, p[k]);
				if(tmp <= 6.25) tmpans++;
			}
			if(ans < tmpans) ans = tmpans;
		}
	printf("%d\n", ans);
    return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值