Circle and Points POJ - 1981(单位圆覆盖最多点)
題意:
給你n個點和點的位置,問單位圓最多能覆蓋多少個點。
題目:
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
分析:
(1).極限思維,我們可以思考,若有這樣的一個覆蓋最多的點,我們可以使至少某一點在這個圓的圓弧上。
(2).先只固定一個點i,該點的單位圓與其他點j的單位圓相交,形成i圓上的一段弧,該弧被j圓覆蓋。最終圓如果在該弧上,則一定能覆蓋j點。那么問題歸結于找出i圓上被覆蓋次數最多的一段弧。
(3).至于弧的表示,可以用相交的兩個點表示,由于所有在弧上的點都可以用角度表示(對于固定一個點,且確定圓為單位圓,半徑為一)類似于一個區間。
(4)問題就轉化成怎么求覆蓋的區域,我們用掃描線的思想,B圓與A圓交于點a,a1與C交于點b,b1,sort排序后,我們令方向為逆時針(兩點我們用極角表示,所以入點一定小于出點),這個時候每兩個交點都有一個入點一個出點,遇到一個入點我們就+1,遇到出點我們就-1,這樣就能表示出被覆蓋的次數。
AC模板:
#include<cmath> #include<cstdio>> #include<iostream> #include<algorithm> using namespace std; const int mm=333; typedef double diy; struct point {diy x,y;//point(){}//point(diy _x,diy _y):x(_x),y(_y){} }g[mm]; struct alpha {diy angle;bool flag; }s[mm]; bool cmp(alpha P,alpha Q) {return P.angle<Q.angle; } diy SqrDis(point P,point Q) {return (P.x-Q.x)*(P.x-Q.x)+(P.y-Q.y)*(P.y-Q.y); } int CircleMaxPoint(int n,diy r) {int i,j,m,sum,ret=n>0;double tmp,rad;for(i=0;i<n;++i){m=0;for(j=0;j<n;++j)if(i!=j&&(tmp=SqrDis(g[i],g[j]))<=4){rad=acos(sqrt(tmp)/2);tmp=atan2(g[j].y-g[i].y,g[j].x-g[i].x);s[m].angle=tmp-rad,s[m++].flag=1;s[m].angle=tmp+rad,s[m++].flag=0;}sort(s,s+m,cmp);for(sum=j=0;j<m;++j){if(s[j].flag)++sum;else --sum;ret=max(ret,sum+1);}}return ret; } int main() {int i,n;while(scanf("%d",&n),n){for(i=0;i<n;++i)scanf("%lf%lf",&g[i].x,&g[i].y);printf("%d\n",CircleMaxPoint(n,1.0));}return 0; }備戰ccpc分站賽ing ,題目分析簡略,見諒,轉載請注明出處。。。。。
總結
以上是生活随笔為你收集整理的Circle and Points POJ - 1981(单位圆覆盖最多点)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 女人唇色暗沉什么原因
- 下一篇: The Last Non-zero Di