• 求最近两点距离算法


    题目连接

    题意:

    求一个圆的半径,半径为在所给坐标点中距离最近两点距离的一半

    思路:

    一开始用暴力枚举求解其最近点,然而超时了。
    wa了很久,最后从网上学习了,分治思想求解最短距离
    更为详细的题解

    主要思想:

    • 先给坐标点用x的方式排序,后给其设计编号
    • 从中间对半,分成两区域,然后分别求其最小值d1,d2在进行比较得到d最小值
    • 但是会出现一种情况就是在两个区域边界点才是最小值的情况
    • 因此我们可以给中间点mid添加范围来求最小值
    • mid为x坐标值,则范围就是mid-d<=x<=mid+d
    • 然后得到答案与d进行比较就得出答案

    代码:

    //看着别人代码打一遍0.0
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    struct point
    {
        double x , y;
    }p[100005];
    
    int a[100005];    //保存筛选的坐标点的索引
    
    int cmpx(const point &a , const point &b)
    {
        return a.x < b.x;
    }
    int cmpy(int a , int b)    //这里用的是下标索引
    {
        return p[a].y < p[b].y;
    }
    inline double dis(point a , point b)
    {
        return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
    }
    inline double min(double a , double b)
    {
        return a < b ? a : b;
    }
    double closest(int low , int high)
    {
        if(low + 1 == high)
            return dis(p[low] , p[high]);
        if(low + 2 == high)
            return min(dis(p[low] , p[high]) , min( dis(p[low] , p[low+1]) , dis(p[low+1] , p[high]) ));
        int mid = (low + high)>>1;
        double ans = min( closest(low , mid) , closest(mid + 1 , high) );    //分治法进行递归求解
        int i , j , cnt = 0;
        for(i = low ; i <= high ; ++i)   //把x坐标在p[mid].x-ans~p[mid].x+ans范围内的点取出来 
        {
            if(p[i].x >= p[mid].x - ans && p[i].x <= p[mid].x + ans)
                a[cnt++] = i;       //保存的是下标索引
        }
        sort(a , a + cnt , cmpy);   //按y坐标进行升序排序  
        for(i = 0 ; i < cnt ; ++i)
        {
            for(j = i+1 ; j < cnt ; ++j)
            {
                if(p[a[j]].y - p[a[i]].y >= ans)   //注意下标索引
                    break;
                ans = min(ans , dis(p[a[i]] , p[a[j]]));
            }
        }
        return ans;
    }
    int main(void)
    {
        int i,n;
        while(scanf("%d",&n) != EOF)
        {
            if(!n)
                break;
            for(i = 0 ; i < n ; ++i)
                scanf("%lf %lf",&p[i].x,&p[i].y);
            sort(p , p + n , cmpx);
            printf("%.2lf
    ",closest(0 , n - 1)/2);  
        }
        return 0;
    }
    

    体会

    见识到了sort的另外一种用法,利用递归函数进行分治。。等等一系列新写法

  • 相关阅读:
    215. Kth Largest Element in an Array
    214. Shortest Palindrome
    213. House Robber II
    212. Word Search II
    210 Course ScheduleII
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    206. Reverse Linked List
    sql 开发经验
  • 原文地址:https://www.cnblogs.com/q1076452761/p/7143283.html
Copyright © 2020-2023  润新知