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的算法. 一般这种覆盖问题你可以假设有两个点在圆的边界上,那么每次产生的圆 ...
随机推荐
- Oracle SQL语句性能优化方法大全
Oracle SQL语句性能优化方法大全 下面列举一些工作中常常会碰到的Oracle的SQL语句优化方法: 1.SQL语句尽量用大写的: 因为oracle总是先解析SQL语句,把小写的字母转换成大写的 ...
- this经典试题
<body> <div class="container"> <h3>输出内容</h3> <pre> var name ...
- Java微信公众号开发----关键字自动回复消息
在配置好开发者配置后,本人第一个想要实现的是自动回复消息的功能,说明以下几点: 1. url 仍然不变,还是开发配置里的url 2. 微信采用 xml 格式传输数据 3.微信服务器传给我们的参数主要有 ...
- 设置通过Maven创建的工程的JDK的版本,更改conf/settings.xml
eclipse提示警告如下: Build path specifies execution environment J2SE-1.5. There are no JREs installed in t ...
- mysql 备份 常用脚本
全备: innobackupex --defaults-file=/data/mysql3316/my3316.cnf --user=root --password=mysqlpass /data/b ...
- php 正则表达式中的 .*? 表示什么意思
我们知道我 .* 是任意字符,有的时候比较困惑在加个?什么意思. ?是非贪婪模式.*会匹配后面的一切字符,就是到结束的意思加?后就是不贪婪模式,这时要看?后边的字符是什么了,如.*?"的意思 ...
- sphinx 快速使用
建立配置文件 例可以参照之前的模板新建一个配置文件 sphinx/etc目录 #MySQL数据源配置,详情请查看:http://www.coreseek.cn/products-install/mys ...
- 重写laravel 异常抛出处理
所有异常错误都由类App\Exceptions\Handler处理,该类包含两个方法:report和render. 这里我们只看render方法,该方法会将异常渲染到HTTP响应中,就是说上面的错误信 ...
- 【android】android对位图文件的支持
Android 支持以下三种格式的位图文件:.png(首选)..jpg(可接受)..gif(不建议).
- 【php】命名空间的影响
命名空间对代码的影响 类(包含抽象类和traits) 接口 常量 函数