• hdu1007


    /*
    *最近点对的问题
    */

    #include 
    #include 
    #include 
    using namespace std;
    const int SIZE = 100005;
    const int L = -1;
    const int R = 1;

    typedef struct
    {
    int index;
    double x;
    double y; /用于记录坐标点/
    }coord;

    coord num[SIZE], c[SIZE]/用作辅助数组/;

    double getDistance(coord &bi1, coord &bi2) /求得两点之间的距离/
    {
    return sqrt(pow(bi1.x - bi2.x, 2.0) + pow(bi1.y - bi2.y, 2.0));
    }

    bool cmpx(coord &bi1, coord &bi2)
    {
    if (bi1.x == bi1.x)
    return bi1.y < bi2.y;
    else
    return bi1.x < bi2.x;
    }

    bool cmpy(coord &bi1, coord &bi2)
    {
    if (bi1.y == bi2.y)
    return bi1.x < bi2.x;
    else
    return bi1.y < bi2.y;
    }

    inline double min(double &bi1, double &bi2, double &bi3)
    {
    double minLength;
    minLength = bi1 > bi2 ? bi2 : bi1;
    minLength = minLength > bi3 ? bi3 : minLength;
    return minLength;
    }

    inline double minDist(double &bi1, double &bi2)
    {
    if (bi1 > bi2)
    return bi2;
    return bi1;
    }

    double divide_conquer(int low, int high) /分治法求最小距离/
    {
    double dis;
    int count = high - low;
    if (count == 0)
    {
    return 0;
    }
    else if (count == 1) /两个数/
    {
    dis = getDistance(num[low], num[high]);
    }
    else if (count == 2) /三个数/
    {
    double temp1, temp2, temp3;
    temp1 = getDistance(num[low], num[low + 1]);
    temp2 = getDistance(num[low + 1], num[high]);
    temp3 = getDistance(num[low], num[high]);
    dis = min(temp1, temp2, temp3);
    }
    else /大于三个数的情况/
    {
    double leftmin, rightmin, min;
    int mid = (low + high) / 2;
    int p = 0;
    int i, j;

        leftmin = divide_conquer(low, mid);  /*求得左边部分的最小值*/  
        rightmin = divide_conquer(mid + 1, high);  /*求得右边部分的最小值*/  
        dis = minDist(leftmin, rightmin);  
    
        /*下面从所有坐标点中找出所有x在leftCoord到rightCoord之间的点*/  
        for (i = low; i <= mid; i++)  
        {  
            double leftCoord = num[mid].x - dis;  
            if (num[i].x >= leftCoord)  
            {  
                c[p].index = L;  /*标识属于左边部分*/  
                c[p].x = num[i].x;  
                c[p].y = num[i].y;  
                p++;  
            }  
        }  
        for ( ; i <= high; i++)  
        {  
            double rightCoord = num[mid].x + dis;  
            if (num[i].x <= rightCoord)  
            {  
                c[p].index = R;  /*标识属于右边部分*/  
                c[p].x = num[i].x;  
                c[p].y = num[i].y;  
                p++;  
            }  
        }  
        sort(c, c + p, cmpy);   /*找到的点再从小到大按照y排序一次*/  
        for (i = 0; i < p; i++)  
        {  
    

    /*错误出现在这里,上面我是只搜索了左边,并且只计算了7个y值比c[i].y大的点到c[i]的距离,
    可是实际上y值比c[i].y小的点也有可能与c[i]取得最小值,所以说上面的程序有错误。真正正确
    的解答如下,那就是要搜索所有的点,并计算7个y值比c[i].y大的点到c[i]的距离,由于距离是两个
    点之间产生的,一个点的y值比另一个点小,那么必然有另一个点的y值比一个点的大,由于这种关系,
    从而保证了搜索出来的是最小的距离!
    */
    for (j = 1; (j <= 7) && (i + j < p); j++)
    {
    if (c[i].index != c[i + j].index) /最小值只可能出现在两个分别属于不同的边的点上/
    {
    min = getDistance(c[i], c[i + j]);
    if(min < dis)
    dis = min;
    }
    }
    }
    }
    return dis;
    }

    int main ()
    {
    int n;
    while (cin >> n && n != 0)
    {
    double result = 0;

        for (int i = 0; i < n; i++)  
        {  
            num[i].index = 0;  
            cin >> num[i].x >> num[i].y;  
        }  
    
        sort (num, num + n, cmpx);  
    
        result = divide_conquer(0, n - 1);  
    
        printf("%.2lf
    ", result / 2);  
    }  
    //system ("pause");  
    return 0;  
    

    }

  • 相关阅读:
    Windows Phone 开发——相机功能开发
    IE8 margin:0 auto 不能居中显示的问题
    YUI Compressor JS和CSS压缩工具使用方式(使用前安装JDK)
    Javascript日常编码中的一些常见问题
    NODESCHOOL
    js动态加载css和js
    JS this用法详解
    getElementsByTagName( )方法
    js 停止事件冒泡 阻止浏览器的默认行为(比如阻止超连接 # )
    跨浏览器的事件对象
  • 原文地址:https://www.cnblogs.com/wangkun1993/p/6268997.html
Copyright © 2020-2023  润新知