zoukankan      html  css  js  c++  java
  • 最接近点对问题(分治法)

     来 自

     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

  • 相关阅读:
    LeetCode Path Sum II
    LeetCode Longest Palindromic Substring
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Binary Tree Maximum Path Sum
    LeetCode Find Peak Element
    LeetCode Maximum Product Subarray
    LeetCode Intersection of Two Linked Lists
    一天一个设计模式(1)——工厂模式
    PHP迭代器 Iterator
  • 原文地址:https://www.cnblogs.com/yezhennan/p/5443597.html
Copyright © 2011-2022 走看看