zoukankan      html  css  js  c++  java
  • 求最近两点距离算法

    题目连接

    题意:

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

    思路:

    一开始用暴力枚举求解其最近点,然而超时了。
    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的另外一种用法,利用递归函数进行分治。。等等一系列新写法

  • 相关阅读:
    我渴望自由和成功(愿与君共勉)
    gdb使用 和core dump文件调试
    谷歌浏览器快捷键大全
    Android适屏
    BestCoder Round #33
    NAT&amp;Port Forwarding&amp;Port Triggering
    程序员应该学习的书
    java代码调用rtx发送提醒消息
    js实现excel导出
    一个跨界程序员:不务正业的这几年,我如何让自己的收入翻了十倍(转)
  • 原文地址:https://www.cnblogs.com/q1076452761/p/7143283.html
Copyright © 2011-2022 走看看