POJ 1106 极角排序

题意:

给定半圆的圆心和半径和n个点,求能在半圆内的最多的点数。

题解:

先把所有的在圆外的点删除,然后求出所有的点关于圆心的极角,然后排序,因为是环形的,极角复制一份加在原来的后面,维护双指针即可~

View Code
 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <cmath>
 7 
 8 #define PI 3.141592653589
 9 #define EPS 1e-7
10 #define N 600
11 
12 using namespace std;
13 
14 struct PO
15 {
16     double x,y,angle;
17 }p[N];
18 
19 int n,ans;
20 double sr;
21 
22 inline bool cmp(const PO &a,const PO &b)
23 {
24     return a.angle<b.angle;
25 }
26 
27 inline int doublecmp(double x)
28 {
29     if(x>EPS) return 1;
30     else if(x<-EPS) return -1;
31     return 0;
32 }
33 
34 inline double get_dis2(PO &a,PO &b)
35 {
36     return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
37 }
38 
39 inline void read()
40 {
41     n=0;
42     int tmp;scanf("%d",&tmp);
43     for(int i=1;i<=tmp;i++)
44     {
45         ++n;
46         scanf("%lf%lf",&p[n].x,&p[n].y);
47         if(doublecmp(get_dis2(p[n],p[0])-sr*sr)==1) n--;
48         else p[n].angle=atan2(p[n].y-p[0].y,p[n].x-p[0].x);
49     }
50 }
51 
52 inline void go()
53 {
54     ans=0;
55     sort(p+1,p+1+n,cmp);
56     for(int i=1;i<=n;i++) p[i+n].angle=p[i].angle+2*PI;
57     for(int g1=1,g2=1;g1<=n&&g2<=n+n;g2++)
58         if(doublecmp(p[g2].angle-p[g1].angle-PI)==1)
59         {
60             ans=max(g2-g1,ans);
61             g1++;
62         }
63     printf("%d\n",ans);
64 }
65 
66 int main()
67 {
68     while(scanf("%lf%lf%lf",&p[0].x,&p[0].y,&sr),doublecmp(sr)>=0) read(),go();
69     return 0;
70 }
原文地址:https://www.cnblogs.com/proverbs/p/2923785.html