• 最接近点对问题(分治法)


     来 自

     http://www.ahhf45.com/info/Data_Structures_and_Algorithms/problems/problem_set/ndp/problem.htm

     

    问题描述

        在应用中,常用诸如点、圆等简单的几何对象代表现实世界中的实体。在涉及这些几何对象的问题中,常需要了解其邻域中其他几何对象的信息。例如,在空中交通控制问题中,若将飞机作为空间中移动的一个点来看待,则具有最大碰撞危险的2架飞机,就是这个空间中最接近的一对点。这类问题是计算几何学中研究的基本问题之一。下面我们着重考虑平面上的最接近点对问题。

    最接近点对问题的提法是:给定平面上n个点,找其中的一对点,使得在n个点的所有点对中,该点对的距离最小。

    严格地说,最接近点对可能多于1对。为了简单起见,这里只限于找其中的一对。

    代码如下:

    #include <iostream>
    #include <fstream>
    #include <math.h>
    using namespace std;
    
    ifstream fin("in.txt");
    struct point
    {
        int x;
        int y;
    }*p;
    
    
    void sort(point *p,int n)
    {
        point t;
        for(int i=1;i<n;i++)
        {
            t = p[i];
            for(int j=i-1;j>=0;j--)
            {
                if(t.x < p[j].x) p[j+1]=p[j];
                else break;
            }
            p[j+1]=t;
        }
    }
    
    double Distance(int i,int j)
    {
        return sqrt((p[j].x-p[i].x)*(p[j].x-p[i].x)+(p[j].y-p[i].y)*(p[j].y-p[i].y));
    }
    
    double Closest(int begin,int end,int &one,int &two)
    {    
        if(end-begin==1)    //两个点的情况
        {
            one = begin; two = begin+1;
            return Distance(begin,end);
        }
        double min,dist; 
        if(end-begin==2)      //三个点的情况
        {
            min = Distance(begin,begin+1);
            one = begin;    two = begin+1;
            dist = Distance(begin,end);
            if(min>dist){min=dist;two = end;}
            dist = Distance(begin+1,end);
            if(min>dist){min=dist;one = begin+1;}
            return min;
        }
    
        int mid = (begin+end)/2;               //多余三个点 分治法求解
        dist = Closest(begin,mid,one,two);
        int three=0,four=0;
        double dist2 =  Closest(mid,end,three,four); 
        if(dist<dist2)                           //对结果合并处理
        {min = dist;}
        else{
            min = dist2;
            one = three; two = four;
        }
        int i,j,num;
        double xia,shang;                  //关键部分!
        xia = p[mid].x-min;
        for(i=mid;i>=0;i--)             
        {
            if(p[i].x<xia)break;
            num = mid+6 < end ? mid+6:end;
            shang = p[i].y+min;
            for(j=mid+1;j<num;j++)
            {
                if(p[j].x-p[i].x > min)break;
                if(p[j].y > shang)continue;
                dist = Distance(i,j);
                if(min>dist)
                {
                    min=dist;
                    one = i;
                    two = j;
                
                }
            }
        }
        return min;
    }
    
    int main()
    {
        int n;
        fin>>n;
        p= (point *)malloc(sizeof(point)*n);
        int i;
        for(i=0;i<n;i++)
        {
            fin>>p[i].x>>p[i].y;
        }
        sort(p,n);
        for(i=0;i<n;i++)
            cout<<p[i].x<<" ";
        cout<<endl;
        int one=0,two=0;
        cout<<"The closest distance is "<<Closest(0,n,one,two)<<endl;
        cout<<"<"<<p[one].x<<","<<p[one].y<<">"<<endl;
        cout<<"<"<<p[two].x<<","<<p[two].y<<">"<<endl;
        return 0;
    }

    输入文件 in.txt:

    10

    43 67
    99 35
    81 36
    64 78
    45 65
    71 94
    24 61
    21 34
    5 29
    31 51

    结果:

    5 21 24 31 43 45 64 71 81 99   //按x轴从小到大排序
    The closest distance is 2.82843
    <43,67>
    <45,65>
    Press any key to continue

  • 相关阅读:
    PAT (Basic Level) Practise 1013 数素数
    PAT (Basic Level) Practise 1014 福尔摩斯的约会
    codeforces 814B.An express train to reveries 解题报告
    KMP算法
    rsync工具
    codeforces 777C.Alyona and Spreadsheet 解题报告
    codeforces 798C.Mike and gcd problem 解题报告
    nginx + tomcat多实例
    MongoDB副本集
    指针的艺术(转载)
  • 原文地址:https://www.cnblogs.com/yezhennan/p/5443597.html
Copyright © 2020-2023  润新知