hdu 1007 分治

来源:互联网 发布:游戏设计软件下载 编辑:程序博客网 时间:2024/05/23 23:10

题意:求最近点对

暴力一定超时,分治:(代码参考别人)

求最大的环,此环只能套中一个,所以只能先找出距离最小的两点且其距离就是环的直径,不然该环就有可能一次套中两个环。所以这题的题意是:求最近点对。

#include<iostream>#include<string.h>#include<stdio.h>#include<math.h>#include<algorithm>#define DX(x) ((x)*(x))using namespace std;const int MAX=100000+1;int n;struct Point{    double x,y;    int index;}a[MAX],b[MAX],c[MAX];double getdis(Point a,Point b){       return sqrt(DX(a.x-b.x)+DX(a.y-b.y));}/*double getmin(double a,double b){       if(a<b) return a;       else return b;}*/inline double getmin(double a, double b) {     return a < b ? a : b; }bool cmpx(const Point& a,const Point& b){     if(a.x==b.x) return a.y<b.y;     return a.x<b.x;}bool cmpy(const Point& a,const Point& b){     if(a.y==b.y) return a.x<b.x;     return a.y<b.y;}void merget(Point b[],Point c[],int p,int m,int q)   //合并 {     int i,j,k;     for(i=p,k=p,j=m+1;i<=m&&j<=q;)   //两边都是按y从小到大排列,所以只用比较                                      //两边的最左方的y值,即可得总的y的升序排列      {          if(c[i].y>c[k].y)  b[k++]=c[i], j++;          else  b[k++]=c[i],i++;     }     while(i<=m)  b[k++]=c[i++];     while(j<=q)  b[k++]=c[j++];}double closet(Point a[],Point b[],Point c[],int p,int q){       double d1,d2;       if(q - p == 1) return getdis(a[p],a[q]);       if(q - p == 2)       {            double x1=getdis(a[p],a[p+1]);            double x2=getdis(a[p],a[q]);            double x3=getdis(a[p+1],a[q]);            return getmin(x1,getmin(x2,x3));       }                  int m=(q + p)/2,i,j,k;           //为了正确 的分治、           for(i = p,j = p,k = m + 1; i <=q; ++i)           {                if(b[i].index<=m) c[j++]=b[i];                else c[k++]=b[i];           }            d1=closet(a,c,b,p,m);           d2=closet(a,c,b,m+1,q);           merget(b,c,p,m,q);           double dm=getmin(d1,d2);           for(i = p, k = p;i <= q;++i)           {               if(fabs(b[i].x-b[m].x) < dm)                    c[k++]=b[i];           }           for(i = p; i < k; ++i)           {                 for(j = i + 1; j < k && c[j].y - c[i].y < dm; ++j)                 {                      double temp=getdis(c[i],c[j]);                      if(temp < dm) dm=temp;                 }            }           return dm;}int main(){        while(scanf("%d",&n)!=EOF&&n!=0)    {         for(int i=0;i<n;i++)            {scanf("%lf%lf",&a[i].x,&a[i].y); }         sort(a,a+n,cmpx);         for(int i=0;i<n;i++)  a[i].index=i;         memcpy(b,a,n*sizeof(b[0]));         sort(b,b+n,cmpy);         double dis=closet(a,b,c,0,n-1);         printf("%.2lf\n",dis/2.0);         }    return 0;}



注1: