分治法求最近点对,模板题
第二题稍微判断一下即可
总结一下分治法基本写法:
第一部分:边界判断
第二部分:递归函数
第三部分:区间合并
第一题:
#include<stdio.h> #include<math.h> #include<algorithm> using namespace std; const double eps=1e-8; struct Point { double x,y; }p[100005],tmp[100005]; int n; double dist(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int cmpxy(Point a,Point b){ if(a.x!=b.x) return a.x<b.x; return a.y<b.y; } int cmpy(Point a,Point b){ return a.y<b.y; } double Closest_Pair(int left,int right){ double d=1e20; if(left==right) return d; if(left+1==right) return dist(p[left],p[right]); int mid=(left+right)>>1; double d1=Closest_Pair(left,mid); double d2=Closest_Pair(mid+1,right); d=min(d1,d2); int k=0; for(int i=left;i<=right;i++){ if(fabs(p[mid].x-p[i].x)<d+eps) tmp[k++]=p[i]; } sort(tmp,tmp+k,cmpy); for(int i=0;i<k;i++){ for(int j=i+1;j<k&&tmp[j].y-tmp[i].y<d+eps;j++){ d=min(d,dist(tmp[i],tmp[j])); } }
第二题:
/* * Author: lj94093 * Created Time: 2015/5/20 星期三 下午 8:06:52 * File Name: Raid.cpp */ #include<stdio.h> #include<string.h> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<math.h> using namespace std; #define out(x) cout<<#x<<": "<<x<<endl const double eps(1e-8); const int maxn=100100; const long long inf=-1u>>1; typedef long long ll; struct Point{ double x,y; int kind; }p[maxn*2],tmp[maxn*2]; int t,n; int cmpxy(Point a,Point b){ if(a.x!=b.x) return a.x<b.x; return a.y<b.y; } int cmpy(Point a,Point b){ return a.y<b.y; } void init() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%lf%lf",&p[i].x,&p[i].y); p[i].kind=0; } for(int i=0;i<n;i++) { scanf("%lf%lf",&p[i+n].x,&p[i+n].y); p[i+n].kind=1; } sort(p,p+2*n,cmpxy); } double dist(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double work(int left,int right) { double d=inf; if(left==right) return d; if(left+1==right){ if(p[left].kind==p[right].kind) return d; else return dist(p[left],p[right]); } int mid=(left+right)>>1; d=min(work(left,mid),work(mid+1,right)); int k=0; for(int i=left;i<=right;i++){ if(fabs(p[i].x-p[mid].x)<d-eps) tmp[k++]=p[i]; } sort(tmp,tmp+k,cmpy); for(int i=0;i<k;i++){ for(int j=i+1;j<k && p[j].y-p[i].y<d-eps;j++){ if(p[i].kind==p[j].kind) continue; d=min(d,dist(p[i],p[j])); } } return d; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif scanf("%d",&t); while(t--){ init(); printf("%.3f\n",work(0,2*n-1)+eps); } return 0; }
时间: 2024-10-13 03:55:43