zoukankan      html  css  js  c++  java
  • 最近点对及距离

     距离上次写算法题目已经有半个月了吧。从20号回学校参加毕业典礼,和舍友,和同学疯狂了十天。很高兴,也很伤感。终于,我也本科毕业了。最终,分离的那一天还是要到来

    的,我最舍不得的是和海哥还有小强的感情,再也听不到他们的嬉戏打闹的声音,再也听不到他们的狂叫,再也看不到他们疯疯癫癫的样子。现在回想起我们一起的点点滴滴,我的眼泪又忍不住要往下滴了。在这我只想偷偷的告诉你们,我想你们了。

      现在我们都开始了自己新的生活了,虽然说我们不能活在过去,但是我们也要相离莫相忘。一定要彼此挂念!

    题目描述:

      给定平面N个点的坐标,找出距离最近的点对以及最近的距离。

    解题思路:

      用分治的方法来解决。按x轴排序,然后找中间的点, 把所有点分成左右两部分,递归求左右两边的最短距离。当然还要考虑左边和右边点的距离。

      好了,关于问题的描述网上有很多很多,我也懒得写了,也写不了那么好。我也是先看了别人的分析,才写出来的。

    代码:

    //求平面内最近的两点及距离
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    typedef struct{
        int x;
        int y;
    }POINT;
    
    //记录最近点对以及距离
    typedef struct{
        int a;
        int b;
        double dMinDist;
    }MinestPoint;
    
    POINT pointAll[100];
    POINT pointY[100];
    MinestPoint nMinestPoint;
    
    
    MinestPoint Min(MinestPoint a, MinestPoint b)
    {
        if (a.dMinDist < b.dMinDist) return a;
        else return b;
    }
    
    //按x轴排序
    int cmpX(const void *a, const void *b)
    {
        POINT *p1,*p2;
        p1 = (POINT *)a; p2 = (POINT *)b;
        if (p1->x == p2->x) return p1->y - p2->y;
        return p1->x - p2->x;
    }
    
    //按y轴排序
    int cmpY(const void *a, const void *b)
    {
        POINT *p1,*p2;
        p1 = (POINT *)a; p2 = (POINT *)b;
        if (p1->y == p2->y) return p1->x - p2->x;
        return p1->y - p2->y;
    }
    
    
    int Input() 
    {
        int i=0,n;
        FILE *fp;
    
        fp = fopen("in.txt","r");
        if (fp == NULL)
        {
            printf("fopen error.
    ");
            return -1;
        }
        
        fscanf(fp,"%d",&n);
        while (i < n)
        {
            fscanf(fp,"%d%d",&pointAll[i].x,&pointAll[i].y);
            i++;
        }
        qsort(pointAll,n,sizeof(POINT),cmpX);
    
        for (i = 0; i < n; i++)
        {
            printf("(%d,%d) ",pointAll[i].x,pointAll[i].y);
        }
        printf("
    ");
        return n;
    }
    
    double Dist(POINT a, POINT b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
    }
    
    MinestPoint DivideConque(int left, int right)
    {
        int nMid,nCnt,i,j;
        double nDist;
        MinestPoint nMinLeft,nMinRight;
        
        if (left == right) 
        {
            if (1000 == nMinestPoint.dMinDist )
            {
                nMinestPoint.a = nMinestPoint.b = left;
            }
            return nMinestPoint;
        }
        if (left+1 == right)
        {
            nDist = Dist(pointAll[left],pointAll[right]);
            if ( nDist < nMinestPoint.dMinDist)
            {
                nMinestPoint.a = left;
                nMinestPoint.b = right;
                nMinestPoint.dMinDist = nDist;
            }
            return nMinestPoint;
        }
        
        nMid = (right + left)/2;
        nMinLeft = DivideConque(left,nMid);
        nMinRight = DivideConque(nMid+1,right);
        
        nMinestPoint = Min(nMinLeft,nMinRight);
    
        //选取在中线附近的点
        nCnt = 0;
        for (i = left; i <= right; i++)
        {
            if (pointAll[i].x <= pointAll[nMid].x + nMinestPoint.dMinDist &&
                pointAll[i].x >= pointAll[nMid].x - nMinestPoint.dMinDist)
            {
                pointY[nCnt++] = pointAll[i];
            }
        }
    
        qsort(pointY,nCnt,sizeof(POINT),cmpY);
    
        for (i = 0; i < nCnt; i++)
        {
            for (j = i + 1; j < nCnt; j++)
            {
                if (pointY[j].y - pointY[i].y > nMinestPoint.dMinDist)
                    break;
                nDist = Dist(pointY[i],pointY[j]);
                if (nDist < nMinestPoint.dMinDist)
                {
                    nMinestPoint.a = i;
                    nMinestPoint.b = j;
                    nMinestPoint.dMinDist = nDist;
                }
            }
        }
        return nMinestPoint;
    }
    
    
    int main()
    {
        int n,a,b;
        nMinestPoint.dMinDist = 1000;  //假设1000为正无穷
    
        n = Input();
        DivideConque(0,n-1);
        a = nMinestPoint.a;
        b = nMinestPoint.b;
        
        printf("Minest Dist is:%f.
    ",nMinestPoint.dMinDist);
        printf("the point a:(%d,%d),point b is:(%d,%d).
    ",pointAll[a].x,pointAll[a].y,
            pointAll[b].x,pointAll[b].y);
        return 0;
    }

    2013/7/7 20:53
  • 相关阅读:
    pointer-like classes, 关于智能指针
    non-explicite-one-argumen-constructor
    车道标线分割与分类
    matlab变量更新
    matlab求余
    MATLAB中图像的读取与显示
    提取文件一部分内容
    NetCore3.1 使用 mongoDb 存储日志,提升查询效率
    C#代码实现阿里云消息服务MNS消息监听
    盘点这些年我出的书,以及由此得到的收获
  • 原文地址:https://www.cnblogs.com/Jason-Damon/p/3176717.html
Copyright © 2011-2022 走看看