poj pku 1981 Circle and Points 点与圆 位置关系

解决POJ 1981题目:通过枚举任意两点及半径为1确定的圆来找出最多能覆盖多少个点的单位圆。利用点与圆的位置关系进行判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[size=medium][list][*]题目描述: [url]http://poj.org/problem?id=1981[/url]
[*]题目大意: 给定n 个点的坐标, 求单位圆最多可以覆盖(包括在圆上)多少个点.
[*]题目分析: 假设某单位圆能覆盖最多点, 可以右移该单位圆, 使得恰有两个点(或更多)在圆上. 所以思路是,枚举以任意两点,以及半径为1 所确定的圆(有两个,总是选圆心在右, 或在左的那个圆)即可.[/list][/size]

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

#define eps 1e-6

struct Point {
double x, y;
Point() {
x = y = 0.00;
}
};

//返回两点间距
double dist(Point p1, Point p2) {
return sqrt( (p1.x - p2.x) * (p1.x - p2.x) +
(p1.y - p2.y) * (p1.y - p2.y) );
}
//判断点在圆内(包括圆上)
bool dot_on_in_circle(Point p, Point c, double r) {
return (dist(p, c) < r + eps);
}
//返回p1, p2, 以及半径1, 所确定的圆的圆心(只是其中一个圆心)
//保证dist(p1, p2) <= 2.0
Point circle(Point p1, Point p2) {
Point mid, ret;
mid.x = (p1.x + p2.x) / 2;
mid.y = (p1.y + p2.y) / 2;

double a = dist(p1, mid);
double d = sqrt(1.0 - a * a);

if(fabs(p1.x - p2.x) <= eps) {
ret.x = mid.x + d;
ret.y = mid.y;
return ret;
}

double alpha = atan((p1.y - p2.y) / (p1.x - p2.x));
//double alpha = atan(a / d);

ret.x = mid.x + d * sin(alpha);
ret.y = mid.y - d * cos(alpha);
return ret;
}

int main() {
//freopen("in.txt", "r", stdin);

int n, i, j, k, count, max;
Point dot[305], cent;
while(scanf("%d", &n) != EOF && n) {
max = 1;
for(i = 0; i < n; i++)
scanf("%lf %lf", &dot[i].x, &dot[i].y);

for(i = 0; i < n; i++) {
for(j = i + 1; j < n; j++) {
if(dist(dot[i], dot[j]) > 2.0)
continue;

count = 0;
cent = circle(dot[i], dot[j]);
for(k = 0; k < n; k++) {
if(dot_on_in_circle(dot[k], cent, 1.0))
count++;
}
if(count > max)
max = count;
}
}
printf("%d\n", max);
}
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值