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 }

 

posted @ 2013-02-23 22:32  proverbs  阅读(826)  评论(0编辑  收藏  举报