题意:
分为两种点,求两种点之间的平面最近点对
题解:
分治法。这个怎么暴力分治都能过。。
吐槽:我用了g++ tle+wa,毛线。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }