POJ 3714 平面最近点对

题意:

分为两种点,求两种点之间的平面最近点对

 

题解:

分治法。这个怎么暴力分治都能过。。

吐槽:我用了g++ tle+wa,毛线。。。

 

View Code
 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdlib>

 4 #include <cstdio>

 5 #include <algorithm>

 6 #include <cmath>

 7 

 8 #define N 222222

 9 #define EPS 1e-7

10 #define INF 1e15

11 

12 using namespace std;

13 

14 struct PO

15 {

16     bool fg;

17     double x,y;

18 }p[N];

19 

20 int n,q1[N],q2[N];

21 

22 inline bool cmp(const PO &a,const PO &b)

23 {

24     return a.x<b.x;

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_dis(PO &a,PO &b)

35 {

36     if(a.fg==b.fg) return INF;

37     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

38 }

39 

40 inline double min(double a,double b)

41 {

42     if(doublecmp(a-b)<=0) return a;

43     return b;

44 }

45 

46 inline void read()

47 {

48     scanf("%d",&n);

49     for(int i=1;i<=n;i++) 

50     {

51         scanf("%lf%lf",&p[i].x,&p[i].y);

52         p[i].fg=1;

53     }

54     for(int i=n+1;i<=(n<<1);i++)

55     {

56         scanf("%lf%lf",&p[i].x,&p[i].y);

57         p[i].fg=0;

58     }

59     n<<=1;

60 }

61 

62 inline double getmindis(int l,int r)

63 {

64     if(l==r) return INF;

65     if(l+1==r) return get_dis(p[l],p[r]);

66     int mid=(l+r)>>1;

67     double lmindis=getmindis(l,mid);

68     double rmindis=getmindis(mid+1,r);

69     double mindis=min(lmindis,rmindis);

70     int cnt1=0,cnt2=0;

71     

72     for(int i=mid;i>=l;i--)

73     {

74         if(doublecmp(mindis-(p[mid].x-p[i].x))<=0) break;

75         else if(doublecmp(mindis-fabs(p[mid].y-p[i].y))>=0) q1[++cnt1]=i;

76     }

77     for(int i=mid+1;i<=r;i++)

78     {

79         if(doublecmp(mindis-(p[i].x-p[mid].x))<=0) break;

80         else if(doublecmp(mindis-fabs(p[mid].y-p[i].y))>=0) q2[++cnt2]=i;

81     }

82     for(int i=1;i<=cnt1;i++)

83         for(int j=1;j<=cnt2;j++)

84             mindis=min(mindis,get_dis(p[q1[i]],p[q2[j]]));

85     return mindis;

86 }

87 

88 inline void go()

89 {

90     sort(p+1,p+1+n,cmp);

91     printf("%.3lf\n",getmindis(1,n));

92 }

93 

94 int main()

95 {

96     int cas; scanf("%d",&cas);

97     while(cas--) read(),go();

98     return 0;

99 }

 

 上面那个跑的慢

这题考虑精度反而跪了。。。。无语。。。

ZOJ 2107/HDU 1007

View Code
 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdlib>

 4 #include <cstdio>

 5 #include <algorithm>

 6 #include <cmath>

 7 

 8 #define N 2222222

 9 #define EPS 1e-7

10 #define INF 1e10

11 

12 using namespace std;

13 

14 struct PO

15 {

16     double x,y;

17 }p[N],q[N];

18 

19 int n;

20 

21 inline bool cmpx(const PO &a,const PO &b)

22 {

23     return a.x<b.x;

24 }

25 

26 inline bool cmpy(const PO &a,const PO &b)

27 {

28     return a.y<b.y;

29 }

30 

31 inline int doublecmp(double x)

32 {

33     if(x>EPS) return 1;

34     else if(x<-EPS) return -1;

35     return 0;

36 }

37 

38 inline double get_dis(PO &a,PO &b)

39 {

40     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

41 }

42 

43 inline double min(double a,double b)

44 {

45     if(doublecmp(a-b)<=0) return a;

46     return b;

47 }

48 

49 inline void read()

50 {

51     for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);

52 }

53 

54 inline double getmindis(int l,int r)

55 {

56     if(l+1==r) return get_dis(p[l],p[r]);

57     if(l+2==r) return min(get_dis(p[l],p[l+1]),min(get_dis(p[l+1],p[r]),get_dis(p[l],p[r])));

58     int mid=(l+r)>>1;

59     double mindis=min(getmindis(l,mid),getmindis(mid+1,r));

60     int cnt=0;

61     for(int i=l;i<=r;i++)

62         if(doublecmp(mindis-fabs(p[i].x-p[mid].x))>=0) q[++cnt]=p[i];

63     sort(q+1,q+1+cnt,cmpy);

64     for(int i=1;i<=cnt;i++)

65         for(int j=i+1;j<=cnt;j++)

66         {

67             if(q[j].y-q[i].y>=mindis) break;

68             //if(doublecmp(p[j].y-p[i].y-mindis)>=0) break;

69             mindis=min(mindis,get_dis(q[i],q[j]));

70         }

71     return mindis;

72 }

73 

74 inline void go()

75 {

76     sort(p+1,p+1+n,cmpx);

77     printf("%.2lf\n",getmindis(1,n)*0.5);

78 }

79 

80 int main()

81 {

82     while(scanf("%d",&n),n) read(),go();

83     return 0;

84 }

 

你可能感兴趣的:(poj)