Circle and Points
Time Limit: 5000MS   Memory Limit: 30000K
Total Submissions: 8131   Accepted: 2899
Case Time Limit: 2000MS

Description

You are given N points in the xy-plane. You have a circle of radius one and move it on the xy-plane, so as to enclose as many of the points as possible. Find how many points can be simultaneously enclosed at the maximum. A point is considered enclosed by a circle when it is inside or on the circle. 

Input

The input consists of a series of data sets, followed by a single line only containing a single character '0', which indicates the end of the input. Each data set begins with a line containing an integer N, which indicates the number of points in the data set. It is followed by N lines describing the coordinates of the points. Each of the N lines has two decimal fractions X and Y, describing the x- and y-coordinates of a point, respectively. They are given with five digits after the decimal point.

You may assume 1 <= N <= 300, 0.0 <= X <= 10.0, and 0.0 <= Y <= 10.0. No two points are closer than 0.0001. No two points in a data set are approximately at a distance of 2.0. More precisely, for any two points in a data set, the distance d between the two never satisfies 1.9999 <= d <= 2.0001. Finally, no three points in a data set are simultaneously very close to a single circle of radius one. More precisely, let P1, P2, and P3 be any three points in a data set, and d1, d2, and d3 the distances from an arbitrarily selected point in the xy-plane to each of them respectively. Then it never simultaneously holds that 0.9999 <= di <= 1.0001 (i = 1, 2, 3).

Output

For each data set, print a single line containing the maximum number of points in the data set that can be simultaneously enclosed by a circle of radius one. No other characters including leading and trailing spaces should be printed.

Sample Input

3
6.47634 7.69628
5.16828 4.79915
6.69533 6.20378
6
7.15296 4.08328
6.50827 2.69466
5.91219 3.86661
5.29853 4.16097
6.10838 3.46039
6.34060 2.41599
8
7.90650 4.01746
4.10998 4.18354
4.67289 4.01887
6.33885 4.28388
4.98106 3.82728
5.12379 5.16473
7.84664 4.67693
4.02776 3.87990
20
6.65128 5.47490
6.42743 6.26189
6.35864 4.61611
6.59020 4.54228
4.43967 5.70059
4.38226 5.70536
5.50755 6.18163
7.41971 6.13668
6.71936 3.04496
5.61832 4.23857
5.99424 4.29328
5.60961 4.32998
6.82242 5.79683
5.44693 3.82724
6.70906 3.65736
7.89087 5.68000
6.23300 4.59530
5.92401 4.92329
6.24168 3.81389
6.22671 3.62210
0

Sample Output

2
5
5
11 翻译:给定平面坐标N个点,现在想用一个单位圆覆盖尽可能多的点,问最多能覆盖多少点。
思路:朴素做法:枚举任意两个点,求出过这两个点的单位圆的圆心,在看看这个这个单位圆能覆盖多少点,取最大即可。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
#include<functional>
#include<cmath>
#include<stack>
using namespace std;
#define INF 0x3f3f3f3f
const int N_MAX=+;
double EPS = 1e-;
struct P {
double x, y;
P(double x=,double y=):x(x),y(y){}
}ps[N_MAX];
int N; //距离平方
double dist(const P&a,const P&b) {
return (a.x - b.x)*(a.x - b.x)+(a.y - b.y)*(a.y - b.y);//!!!!
}
//找圆心
P find_circle(const P& p1,const P& p2,int flag) {
double phi = atan2(p2.y-p1.y,p2.x-p1.x);
double d = sqrt(dist(p1, p2));
double theta = flag*acos(d/)+phi;
P c;
c.x = p1.x + cos(theta);
c.y = p1.y + sin(theta);
return c;
} void solve() {
int res = ;
for (int i = ; i < N;i++) {
for (int j = i+; j < N;j++) {
if (dist(ps[i], ps[j])<=) {//两点距离小于2,可在一个圆上
P c1 = find_circle(ps[i], ps[j], );
P c2 = find_circle(ps[i], ps[j], -);
int num1=, num2=;
for (int k = ; k < N;k++) {
if (k != i&&k != j) {
if (dist(c1, ps[k]) <= )num1++;
if (dist(c2, ps[k]) <= )num2++;
}
}
res = max(res, num1);
res = max(res, num2);
}
}
}
printf("%d\n",res);
} int main() {
while (scanf("%d",&N)&&N) {
for (int i = ; i < N;i++) {
scanf("%lf%lf",&ps[i].x,&ps[i].y);
}
if (N == ) { printf("1\n"); continue; }
solve();
}
return ;
}

思路2:我们先考虑其中的两个点,分别以这两个点为圆心画单位圆,如果两点距离足够近,则两圆一定会相交并且分别有一段相交的弧,不妨考虑其中的一段弧,如果我们最终需要找的那个圆的圆心就在这段弧上,那么这个圆一定会经过刚才所考虑的那两个点。那么我们每次固定一个点,以这个点为圆心画单位圆与其他的N-1个点为圆心的单位圆分别相交,会在这个点为圆心的圆上产生很多的相交弧,则最终那个圆的圆心若在相交弧重叠部分越多的地方,则可以包含更多的点。

AC代码:

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
#include<functional>
#include<cmath>
#include<stack>
using namespace std;
#define INF 0x3f3f3f3f
const int N_MAX=+;
double EPS = 1e-;
struct P {
double x, y;
P(double x=,double y=):x(x),y(y){}
}ps[N_MAX];
int N;
struct Bow {
double angle;
bool flag;//0代表初始,1代表终止
bool operator <(const Bow&b)const {
return this->angle < b.angle;
}
}bow[N_MAX];
//距离的平方
double dist(const P&a,const P&b) {
return (a.x - b.x)*(a.x - b.x)+(a.y - b.y)*(a.y - b.y);//!!!!
} void solve() {
int res_max = ;//res_max记录单位圆能包含的最多的顶点数
for (int i = ; i < N;i++) {//对于每一个点
int k = ;//记录交弧的个数
for (int j = ; j < N; j++) {
double d = sqrt(dist(ps[i], ps[j]));
if (j != i&&d <= ) {//i,j为圆心的圆相交
double phi = acos(d / );
double theta = atan2(ps[j].y - ps[i].y, ps[j].x - ps[i].x);
bow[k].angle = theta - phi; bow[k++].flag = ;
bow[k].angle = theta + phi; bow[k++].flag = ;
}
}
int res = ;//当前单位圆能包含的顶点数
sort(bow, bow + k);
for (int l = ; l < k;l++) {
if (!(bow[l].flag))res++;
else res--;
res_max = max(res_max, res);
}
}
printf("%d\n",res_max);
} int main() {
while (scanf("%d",&N)&&N) {
for (int i = ; i < N;i++) {
scanf("%lf%lf",&ps[i].x,&ps[i].y);
}
solve();
}
return ;
}

最新文章

  1. virtualbox桥接网络配置--CentOS
  2. 55. Jump Game leetcode
  3. Python 学习笔记01
  4. IOS的APNS和PushKit门道详述
  5. A*算法的实现
  6. java.util.Vector
  7. Codeforces 402A 402B 402C 402D
  8. 使用Raphael 画图(四) 路径(一) (javascript)
  9. windows下搭建PHP环境
  10. 在MVC中利用uploadify插件实现上传文件的功能
  11. 多路复用I/O epoll()
  12. Java Collection 集合类大小调整带来的性能消耗
  13. java数据结构与算法值优先级队列
  14. Cocos2d-x精华教程汇总(第三期) cocos2d-x最新离线API文档下载(最新版3.6更新。。。)
  15. 分布式一致性算法2PC和3PC
  16. ad_imh
  17. codeforces624A
  18. ZJOI2019 Day1游记
  19. Wordpress搭建
  20. Ubuntu云服务器下mysql授权远程登陆

热门文章

  1. javaweb基础(1)_入门
  2. webgis技术在智慧城市综合治理(9+X)网格化社会管理平台(综治平台)的应用研究
  3. 03_4_this关键字
  4. kvm笔记
  5. #ifdef #else #endif #fi #ifndef 的用法
  6. Race condition
  7. 【交互 细节题 思维题】cf1064E. Dwarves, Hats and Extrasensory Abilities
  8. 【莫队】bzoj4542: [Hnoi2016]大数
  9. NFS搭建
  10. Jenkins忘记管理员密码处理