zoukankan      html  css  js  c++  java
  • POJ 1981 最大点覆盖问题(极角排序)

    Circle and Points
    Time Limit: 5000MS   Memory Limit: 30000K
    Total Submissions: 8346   Accepted: 2974
    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. 
     
    Fig 1. Circle and Points

    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
    

    Source

    题意:给出n个点,问用一个单位圆最多能覆盖多少个点。
    思路:把每一个点扩展成单位圆,相交圆会形成相交弧,只需要判断弧被覆盖的最大次数即可,因为弧如果被覆盖,那么以弧上的点为圆心,必然也能覆盖到原来点。

    N^2枚举,保存每段弧的极角范围及端点方向,然后按上端点在前,下端点在后,从大到小对极角排序,从头扫描一遍。

    若经过上端点:ans++ 否则:ans--,取ans最大值即可。

    代码:

     1 //#include"bits/stdc++.h"
     2 #include<sstream>
     3 #include<iomanip>
     4 #include"cstdio"
     5 #include"map"
     6 #include"set"
     7 #include"cmath"
     8 #include"queue"
     9 #include"vector"
    10 #include"string"
    11 #include"cstring"
    12 #include"time.h"
    13 #include"iostream"
    14 #include"stdlib.h"
    15 #include"algorithm"
    16 #define db double
    17 #define ll long long
    18 #define vec vectr<ll>
    19 #define mt  vectr<vec>
    20 #define ci(x) scanf("%d",&x)
    21 #define cd(x) scanf("%lf",&x)
    22 #define cl(x) scanf("%lld",&x)
    23 #define pi(x) printf("%d
    ",x)
    24 #define pd(x) printf("%f
    ",x)
    25 #define pl(x) printf("%lld
    ",x)
    26 //#define rep(i, x, y) for(int i=x;i<=y;i++)
    27 #define rep(i, n) for(int i=0;i<n;i++)
    28 const int N   = 1e4+ 5;
    29 const int mod = 1e9 + 7;
    30 const int MOD = mod - 1;
    31 const int inf = 0x3f3f3f3f;
    32 const db  PI  = acos(-1.0);
    33 const db  eps = 1e-10;
    34 using namespace std;
    35 struct P
    36 {
    37     db x,y;
    38     db ang;
    39     bool in;
    40 };
    41 P a[N],b[N];
    42 db dis(P a,P b){
    43     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    44 }
    45 int cmp(P a,P b){
    46     if(a.ang==b.ang) return a.in>b.in;//上端点在前
    47     return a.ang>b.ang;
    48 }
    49 int main()
    50 {
    51     int n;
    52     while(scanf("%d",&n)==1,n)
    53     {
    54         int ans=1;
    55         for(int i=1;i<=n;i++) cd(a[i].x),cd(a[i].y);
    56         for(int i=1;i<=n;i++)
    57         {
    58             int p=0;
    59             for(int j=1;j<=n;j++){
    60                 if(i==j||dis(a[i],a[j])>2.0+eps) continue;
    61                 db ang=atan2(a[i].x-a[j].x,a[i].y-a[j].y);//i于j的极角
    62                 db tha=acos(dis(a[i],a[j])/2.0);//极角波动范围
    63                 b[p].ang=ang+tha+2*PI,b[p++].in=1;//上端点
    64                 b[p].ang=ang-tha+2*PI,b[p++].in=0;//下端点
    65             }
    66             sort(b,b+p,cmp);
    67             int tmp=1;
    68             for(int j=0;j<p;j++){
    69                 if(b[j].in==1) tmp++;
    70                 else tmp--;
    71                 ans=max(tmp,ans);
    72             }
    73         }
    74         pi(ans);
    75     }
    76     return 0;
    77 }
     
  • 相关阅读:
    利用window.onerror收集js代码异常
    js 基础题复习
    正则12和\1的理解
    CodeReview 方法 规范
    前端的登陆 几种类型
    http协议相关知识
    javascript中apply、call和bind的区别 详细易懂
    http常见的状态码,400,401,403 前端看
    vue中使用file-saver 下载各类文件
    js下载文件到本地各种方法总结
  • 原文地址:https://www.cnblogs.com/mj-liylho/p/8955095.html
Copyright © 2011-2022 走看看