HDU 1007 最近点对

分治法求最近点对

递归将点不断分成小组,计算最短距离。此时的最短距离仅仅是两点都属两块的某一块(这里的分割点是mid点)。

还需要考虑两点分属两块的情况。这时对于选点则把范围缩小到了以mid为中心。再将距离mid点x轴2*mindist范围点考虑在内。在这些点中,再取mid点,留下那些

y的距离不大于middist 的点进行距离计算。

PS:刚开始min函数写错了,写成了max,一直tle.使用max则会导致选取的点越来越多。TLE则就不奇怪了。

对于使用递归方法实现分治,其实质使用了小范围内得到的结果会缩小整体范围内的搜索空间。递归函数要有范围参数噢。

递归的直观理解可以是1 2 3 等简单情况完后得到的结果返回,组拼全局解。

#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn=100005;
int n;
struct P
{
    double x,y;
}p[maxn],ans[maxn];
double min(double a,double b){return a<b?a:b;}
bool cmpx(struct P a,struct P b){return a.x<b.x;}
bool cmpy(struct P a,struct P b){return a.y<b.y;}
double dist(struct P a,struct P b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
double solve(int l,int r)
{
    if(l+1==r)
        return (dist(p[l],p[r]));
        else if(l+2==r)
            return min(dist(p[l],p[l+1]),min(dist(p[l+1],p[r]),dist(p[r],p[l])) );
    int mid=(l+r)>>1;
    double res=min(solve(l,mid),solve(mid+1,r));//这里避免了==mid 的情况
    int cnt=0,i,j;
    for(i=l;i<=r;i++)
    {
        if(fabs(p[i].x-p[mid].x)<=res)
            ans[cnt++]=p[i];
    }
    sort(ans,ans+cnt,cmpy);
    for( i=0;i<cnt;i++)
        for( j=i+1;j<cnt;j++)
    {
        if(ans[j].y-ans[i].y>=res) break;
        res=min(res,dist(ans[i],ans[j]));
    }
    return res;
}
int main()
{
    while(scanf("%d",&n),n)
    {
        int i;
        for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);//输入点
        sort(p,p+n,cmpx);//按x排序
        double res=solve(0,n-1);
        printf("%.2lf\n",res/2);
    }
    return 0;
}
时间: 2024-11-05 16:23:05

HDU 1007 最近点对的相关文章

zoj 2107&amp;&amp;hdu 1007最近点对问题

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1107 Quoit Design Time Limit: 5 Seconds      Memory Limit: 32768 KB Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys

初学算法-分治法求平面上最近点对(Closest Pair)-HDU 1007

本来这个算法在笔者电脑里无人问津过一段时间了,但今天正好做HDU 1007见到了这个问题,今天就来把代码分享出来吧! 我们首先将所有点按照坐标x排序一下,再做一条直线l当作"分割线",方便我们递归. 然后,我们就可以把这些点按照x轴的坐标分为左半部分和右半部分.那么最短距离一定在左半部分.右半部分.跨越左右的点对中的一个. 那么你可能会有疑问了:本来最近点对也一定在这三个区域内,这不还是相当于什么都没干吗? 还真不是.我们可以假设通过递归得到了左边最小距离为d1,右边最小距离为d2,令

hdu 1007 Quoit Design 分治求最近点对

Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 29344    Accepted Submission(s): 7688 Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat

HDU 1007 Quoit Design (分治)

Quoit Design Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded. In the field of Cyberground, the position of each toy is fixed, and the ri

ZOJ 2107 HDU 1007 Quoit Design(最近点对)

最近点对的裸题 利用分治去搞搞即可 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int N = 100005; struct Point { double x, y; void read() { scanf("%lf%lf", &x, &y); } }; b

分治算法应用-最近点对的最小距离-hdu 1007 Quoit Design

题目描述 给出二维平面上的n个点,求其中最近的两个点的距离的一半. 输入包含多组数据,每组数据第一行为n,表示点的个数:接下来n行,每行一个点的坐标.当n为0时表示输入结束,每组数据输出一行,为最近的两个点的距离的一半. 输入样例: 2 0 0 1 1 2 1 1 1 1 3 -1.5 0 0 0 0 1.5 0 输出样例: 0.71 0.00 0.75 题目解析: 采用分治的思想,把n个点按照x坐标进行排序,以坐标mid为界限分成左右两个部分,对左右两个部分分别求最近点对的距离,然后进行合并.

hdu 1007 Quoit Design, 平面最近点对

平面最近点对的经典做法就是分治.所有点先按x再按y排序,然后取中间位置的点,利用其x坐标值将点划分成左右两部分,分别求出两侧的最近点对(设其距离为δ),然后合并.参看下面的图片(来自guyulongcs的专栏,http://blog.csdn.net/guyulongcs/article/details/6841550)合并的时候需要注意,大致有两种做法,一种是把分界线两侧δ范围内的点分别加进一个数组,然后对右侧数组按y坐标值排序,之后依次为每个左侧数组中的点,在右侧数组中寻找与其y坐标值最近的

HDU 1007 Quoit Design【计算几何/分治/最近点对】

Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 58566    Accepted Submission(s): 15511 Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat

hdu 1007 Quoit Design (经典分治 求最近点对)

Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded.In the field of Cyberground, the position of each toy is fixed, and the ring is carefull