zoukankan      html  css  js  c++  java
  • HDU-1007-Quoit Design(分治,点+距离)

    http://acm.hdu.edu.cn/showproblem.php?pid=1007

    题意:

    给出二维平面上的n个点,求其中最近的两个点距离的一般一半。

    输入包含多组数据。每组数据第一行为n,表示点的个数;接下来n行,每行为一个点的坐标。当n为0时表示输入结束。每组数据输出一行,为最近的两个点的距离的一半。

    思路:

    首先暴力枚举肯定不行,数据范围1e5,

    采用分治法,

      1,把n个点按x坐标进行排序,

      2,选取一个中点mid,将所有点分成两个部分(L,mid)和(mid+1,R)

        有三种情况:

        两个点都在左边

        两个点都在右边

        一个在左边,一个在右边 

      3,一二种结果很容易就可以求出得到Lmin和Rmin d=min(Lmin,Rmin);

      对于第三种情况,在以mid为中心,宽为2d的带状区域,选取此区域内的所有点,按照y轴进行排序,一一枚举这些点,更新最小距离即可。

      还可进一步剪枝,如果当前点到达基点的距离已经大于d,那么就可以更换下一个基点。

    PS:对于左边的任意一点,右边的点一定落在一个d*2d的矩形中,且最多只需检查6个点(鸽巣原理),按照y轴排序后,进行线性扫描,此时合并的时间复杂度为O(n*logn),几乎为线性了。

    HDU卡cin,记得用scanf。

    代码:

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string>
    #include<iomanip>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<cmath>
    
    using namespace std;
    const int maxn=1e5+10;
    const int inf=1e10;
    typedef long long ll;
    
    struct node {double x,y;};
    
    bool cmpx(node a,node b){return a.x<b.x;}
    bool cmpy(node a,node b){return a.y<b.y;}
    
    double Dis(node a,node b){return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));}
    
    node a[maxn],b[maxn];
    
    double cal(int s,int e)
    {
        if(s==e) return inf;
    
        int mid=(s+e)/2;
        double d=min(cal(s,mid),cal(mid+1,e));
        
        int num=0;
        for(int i=mid; i>=s&&(a[mid].x-a[i].x)<d; i--) b[num++]=a[i];
        for(int i=mid+1; i<=e&&(a[i].x-a[mid].y)<d; i++) b[num++]=a[i];
    
        sort(b,b+num,cmpy);
        for(int i=0; i<num; i++)
        {
            for(int j=i+1; j<num&&b[j].y-b[i].y<d; j++)
            {
                if(Dis(b[i],b[j])<d)
                 d=Dis(b[i],b[j]);
            }
        }
        return d;
    }
    
    int main()
    {
        int n;
        while(cin>>n&&n)
        {
            for(int i=0; i<n; i++) scanf("%lf%lf",&a[i].x,&a[i].y);
            sort(a,a+n,cmpx);
    
            double ans=cal(0,n-1);
            printf("%.2lf
    ",ans/2.0);
        }
        system("pause");
        return 0;
    }

        

  • 相关阅读:
    iOS6和iOS7代码的适配(3)——坐标适配
    iOS6和iOS7代码的适配(2)——status bar
    iOS6和iOS7代码的适配(1)
    深入Blocks分析
    文字溢出加省略号
    点击图表每一部分触发某事件
    图表添加红线
    比较月份是否存在封装数据
    云上示范区项目总结
    页面之间通过地址栏传参
  • 原文地址:https://www.cnblogs.com/sweetlittlebaby/p/14327859.html
Copyright © 2011-2022 走看看