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的算法. 一般这种覆盖问题你可以假设有两个点在圆的边界上,那么每次产生的圆 ...
随机推荐
- iOS快速开发框架--Bee Framework
Bee Framework是一款iOS快速开发框架,允许开发者使用Objective-C和XML/CSS来进行iPhone和iPad开发,由 Gavin Kwoe 和 QFish 开发并维护. 其早期 ...
- shell脚本,awk取奇数行与偶数行方法。
第一种方法: 第二种方法: 第三种方法:
- 01_9_ServletContext
01_9_ServletContext 1. 例子 public void doGet(HttpServletRequest request, HttpServletResponse response ...
- d3.js--02(data和datum原理)
原文链接: http://d3.decembercafe.org/pages/lessons/3.html 解析一下data和datum原理: datum():绑定一个数据到选择集上 data():绑 ...
- 27. Remove Element@python
Given an array nums and a value val, remove all instances of that value in-place and return the new ...
- vue中文本域限制字数的方法
用watch方法,来限制字数 <template> <div class="box"> <textarea v-model="title&q ...
- 【二分 最小割】cf808F. Card Game
Digital collectible card games have become very popular recently. So Vova decided to try one of thes ...
- vue 顶级组件
快 有时候懒的把一些通用组件写到template里面去,而业务中又需要用到,比如表示loading状态这样组件. 如果是这样的组件,可以选择把组件手动初始化,让组件在整个app生命周期中始终保持活跃. ...
- python爬虫基础18-Chrome调试前端工具
01 Chrome调试 抓包工具原理 Chrome 开发者工具是一套内置在Google Chrome中Web开发和调试工具.使用开发者工具来重演,调试和剖析您的网站. 其中常用的有Elements(元 ...
- python中字典的‘增、删、改、查’
python 字典的'增.删.改.查' 用 ipython 运行情况如下: #新建字典 In [1]: infos = {'name':'dongge','age':18} In [2]: infos ...