• 分治法求最近点对


    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    typedef struct Node
    {
        int x;
        int y;
    };
    bool CmpX(Node a,Node b)
    {
        return a.x<b.x;
    }
    double Distance(Node a,Node b)
    {
        int xx=a.x-b.x;
        int yy=a.y-b.y;
        double distance=xx*xx+yy*yy;
        return sqrt(distance);
    }
    double dfs(Node arr[],int low,int high)
    {
        double result=0.0;
        if((high-low)<3){
            if((high-low)==1){
                double distance=Distance(arr[low],arr[high]);
                return distance;
            }
            else{
                double distance1=Distance(arr[low],arr[low+1]);
                double distance2=Distance(arr[low],arr[low+2]);
                double distance3=Distance(arr[low+1],arr[low+2]);
                return min(distance1,min(distance2,distance3));
            }
        }
        int mid=(low+high)/2;
        double left_result=dfs(arr,low,mid);
        double right_result=dfs(arr,mid+1,high);
        double vec=min(left_result,right_result);
        result=vec;
        vector<Node> s;
        for(int i=low;i<=high;i++){//把这中间区域范围的数拿出来,看看会不会出现更小的。
            if((arr[i].x>arr[mid].x-vec)&&(arr[i].x<arr[mid].x+vec)){
                s.push_back(arr[i]);
            }
        }
        sort(s.begin(),s.end(),CmpX);
        int size=s.size();
        for(int i=0;i<size;i++){
            int k=(i+7)>size?size:(i+7);
            for(int j=i+1;j<k;j++){
                 if(Distance(s.at(i),s.at(j))<result){
                    result=Distance(s.at(i),s.at(j));
                 }
            }
        }
        return result;
    }
    int main()
    {
        int N;
        cin >> N;
        Node arr[N];
        for(int i=0;i<N;i++){
           cin >> arr[i].x >> arr[i].y;
        }
        double rev=dfs(arr,0,N-1);
        cout << rev;
    }

    不断地二分直到三个点时或者两个点时,直接算出他们之间的距离,不断地从两边考虑它们距离的最小值,但是还要考虑第三种情况,那就是一边各一个点,这种情况不能排除在外。

  • 相关阅读:
    C#获取屏幕鼠标所指点的颜色
    C#连接SQLServer数据库基本实现
    论文摘要写法
    红黑树
    递归、迭代和分治法
    逻辑右/左移与算术右/左移
    C 中数字数据类型在不同机器上所占字节数
    十进制转十六进制
    c带头结点的单链表逆置
    求一维数组长度误区
  • 原文地址:https://www.cnblogs.com/sddr/p/10701907.html
Copyright © 2020-2023  润新知