poj 1981 Circle and Points
| Time Limit: 5000MS | Memory Limit: 30000K | |
| Total Submissions: 8131 | Accepted: 2899 | |
| Case Time Limit: 2000MS | ||
Description
Input
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
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 ;
}
poj 1981 Circle and Points的更多相关文章
- POJ 1981 Circle and Points (扫描线)
[题目链接] http://poj.org/problem?id=1981 [题目大意] 给出平面上一些点,问一个半径为1的圆最多可以覆盖几个点 [题解] 我们对于每个点画半径为1的圆,那么在两圆交弧 ...
- poj1981 Circle and Points
地址:http://poj.org/problem?id=1981 题目: Circle and Points Time Limit: 5000MS Memory Limit: 30000K To ...
- poj1981 Circle and Points 单位圆覆盖问题
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Circle and Points Time Limit: 5000MS Me ...
- bzoj1338: Pku1981 Circle and Points单位圆覆盖
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1338 1338: Pku1981 Circle and Points单位圆覆盖 Time ...
- POJ 1981 最大点覆盖问题(极角排序)
Circle and Points Time Limit: 5000MS Memory Limit: 30000K Total Submissions: 8346 Accepted: 2974 ...
- poj 1981(单位圆覆盖最多点问题模板)
Circle and Points Time Limit: 5000MS Memory Limit: 30000K Total Submissions: 7327 Accepted: 2651 ...
- 【POJ 1981】Circle and Points(已知圆上两点求圆心坐标)
[题目链接]:http://poj.org/problem?id=1981 [题意] 给你n个点(n<=300); 然后给你一个半径R: 让你在平面上找一个半径为R的圆; 这里R=1 使得这个圆 ...
- 【POJ 1981 】Circle and Points
当两个点距离小于直径时,由它们为弦确定的一个单位圆(虽然有两个圆,但是想一想知道只算一个就可以)来计算覆盖多少点. #include <cstdio> #include <cmath ...
- POJ - 1981 :Circle and Points (圆的扫描线) hihocoder1508
题意:给定N个点,然后给定一个半径为R的圆,问这个圆最多覆盖多少个点. 思路:在圆弧上求扫描线. 如果N比较小,不难想到N^3的算法. 一般这种覆盖问题你可以假设有两个点在圆的边界上,那么每次产生的圆 ...
随机推荐
- Luogu P1666 前缀单词
校内资格赛题目,差点高一就要\(\tt{AFO}\)了 30分思路 对30%的数据,满足$1≤n≤10 $ 所以我们可以子集枚举,实际得分40pts #include<iostream> ...
- 用Windows Native API枚举所有句柄及查找文件句柄对应文件名的方法
枚举所有句柄的方法 由于windows并没有给出枚举所有句柄所用到的API,和进程所拥有的句柄相关的只有GetProcessHandleCount这个函数,然而这个函数只能获取到和进程相关的句柄数,不 ...
- atomic nonatomic区别
摘要 atomic和nonatomic区别用来决定编译器生成的getter和setter是否为原子操作.atomic提供多线程安全,是描述该变量是否支持多线程的同步访问,如果选择了atomic 那么就 ...
- bash编程之case语句,函数
bash脚本编程:之case语句 条件测试: 0: 成功 1-255: 失败 命令: [ expression ] [[ expression ]] test expression exP ...
- NOIP模拟赛 数列
Problem 2 数列(seq.cpp/c/pas) [题目描述] a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1] (x>3) 求a数列的第n项对1000000007 ...
- 【贪心】bzoj1592: [Usaco2008 Feb]Making the Grade 路面修整
贪心的经典套路:替换思想:有点抽象 Description FJ打算好好修一下农场中某条凹凸不平的土路.按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也 就是说,高度上升与高度下降的路段不能 ...
- Service Mesh是什么技术
https://blog.csdn.net/weixin_38044696/article/details/80257488 Service Mesh是什么技术 2018年05月09日 22:07:4 ...
- PHP计算两个日期相差的年月日时分秒
$start_time = '2017-09-06 15:12:20'; $end_time = '2018-09-08 10:20:45'; get_time($start_time,$end_ti ...
- Linux基础学习-LVM逻辑卷管理遇到的问题
LVM学习逻辑卷管理创建逻辑卷遇到的问题 1 实验环境 系统 内核 发行版本 CentOS 2.6.32-754.2.1.el6.x86_64 CentOS release 6.10 (Final) ...
- 02Vs2013常用路径配置
1.设置头文件路径 项目 -> xxx属性页 -> 配置属性 -> C/C++ -> 常规 -> 附加包含目录. 2.包含 x.lib 库路径 项目 -> xxx属 ...