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 }

 

 

 

你可能感兴趣的:(poj)