zoukankan      html  css  js  c++  java
  • HDU 1007 (最近点对+qsort对结构体的排序!!!)

    http://acm.hdu.edu.cn/showproblem.php?pid=1007

    这题需要注意的有两点:

    一:题目本身,做的思路是分治,像快速排序那样,把所有的点分成差不多的两段,然后再分……直至只剩2个或三个,那样就可以直接算了。

    算法流程:

    1:进入递归过程:如果是该段点数不大于三,那么就可以直接算了,否则用分治法递归解决

    2:将大于四的这堆点分成两部分,得到最小的距离d。但这个距离还不能确定是最小的min,因为有可能一点p在左边,一点q在右边,而他们的距离有可能比d还小,是真正的min

    3:将这堆实现按x排好序的点分成两部分,左边标志L,右边标志R,两个值不同。遍历左边的,找到所有距离中间这个点p[middle].x不超过d的,存在temp里

    再遍历右边的,找到同样符合条件的点存在temp里。

    4.遍历temp,穷举符合条件的点,不断更新min的值,这样的点不超过8过,《编程之美》里有解说。

    5:返回min

    二:贡献N次wa后才发觉可能是排序有问题,早知道就手搓了

    ac代码

    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    #define L -1
    #define R 1
    typedef struct node
    {
        int flag;//标志在左边还是右边
        double x,y;
    }point;
    point p[1000100],temp[1000100];//point存储点信息,minx存储x-d~x+d的点,miny则存储y-d~y+d的点
    int cmpx(const void *a, const void *b)
    {
        point *pa = (point *) a;
        point *pb = (point *) b;
        if (pa->x > pb->x)
            return 1;
        else if (pa->x < pb->x)
            return -1;
        else
            return 0;
    }
    
    int cmpy(const void *a, const void *b)
    {
        int *pa = (int *) a;
        int *pb = (int *) b;
        if (temp[*pa].y > temp[*pb].y)
            return 1;
        else if (temp[*pa].y < temp[*pb].y)
            return -1;
        else
            return 0;
    }
    double minp(double a,double b)
    {
        return a>b?b:a;
    }
    double distance(point a,point b)
    {
        return sqrt(pow(a.x-b.x,2.0)+pow(a.y-b.y,2.0));
    }
    double getmindistance(int left,int right)
    {
        double temp1,temp2,temp3,mindistance;
        int j=0,k=0,i,middle;
        if(left==right)
            return 0;
        else if(left+1==right)
            return distance(p[left],p[right]);//两个点
        else if(left+2==right)
        {
            temp1=distance(p[left],p[left+1]);
            temp2=distance(p[left+1],p[right]);
            temp3=distance(p[left],p[right]);
            return minp(minp(temp1,temp2),temp3);//三个点
        }
        else {
        middle=(left+right)/2;
        temp1=getmindistance(left,middle);
        temp2=getmindistance(middle+1,right);
        mindistance=minp(temp1,temp2);
        for(i=left;i<=middle;i++)
        {
            if(p[middle].x-p[i].x<=mindistance)
            {
                temp[j].flag=L;
                temp[j].x=p[i].x;
                temp[j].y=p[i].y;
                j++;
            }
        }
        for(;i<=right;i++)
        {
            if(p[i].x-p[middle].x<=mindistance)
            {
                temp[j].flag=R;
                temp[j].x=p[i].x;
                temp[j].y=p[i].y;
                j++;
            }
        }
        //qsort(temp,j,sizeof(temp[0]),cmpy);这里的排序是按另一种做法时才用到的
        for(i=0;i<j;i++)
           for(k=1;(k<8)&&(i+k<j);k++)
           {
               if(temp[i].flag!=temp[i+k].flag)
                  mindistance=minp(distance(temp[i],temp[i+k]),mindistance);
           }
           return mindistance;
        }
    }
    int main()
    {
        int n,i;
        double answer;
        while(scanf("%d",&n),n)
        {
            for(i=0;i<n;i++)
              {
                  scanf("%lf%lf",&p[i].x,&p[i].y);
                  p[i].flag=0;
              }
            qsort(p,n,sizeof(p[0]),cmpx);//先按x排序
            answer=getmindistance(0,n-1);
            printf("%.2lf
    ",answer/2.0);//题目要求的是半径
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Spring jar包功能
    maven pom.xml详细介绍,必须留一份
    redis基本类型以及优点特性
    如何实现网站的防盗链?
    php几种常见排序算法
    批量去除文件的BOM头
    Keepalived实现双机热备
    nginx配置文件详解
    源码编译安装lnmp环境
    nginx实现https网站设置
  • 原文地址:https://www.cnblogs.com/huzhenbo113/p/3275857.html
Copyright © 2011-2022 走看看