/*     Copyright    by ZhongMing-Bian     Jan,6,2010   */
/*             分治法解决最小套圈问题                  */
/*        Jan,11  debug ;input question                */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define  MAX_POINTS  100000    /*坐标点数的最大值 */
#define MAX_TEST 100     /*最大测试次数*/

typedef  struct  {    /*定义坐标点*/
    float  x;
    float  y;
}Point;

float  dist(Point  a,  Point  b)  {    /*求两个坐标点之间的距离*/
    return  sqrt((float)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
  }

float  Nearest(Point*  points,  int  n){   /*求最小距离*/
    float temp1,temp2,temp3,temp,nearest;
    float left,right,d;    /*当n小于4时,T(n)=O(1);*/
    int i,j;
    if(n==1)  return  999999999;             /*一个点情形,返回值模拟无穷*/
    if(n==2)  return  dist(points[0],  points[1]);  /*两个点情形*/
    if(n==3){                          /*三个点情形*/
        temp1=dist(points[0],  points[1]);
        temp2=dist(points[0],  points[2]);
        temp3=dist(points[1],  points[2]);
        return  temp3<((temp1<temp2)?temp1:temp2)?temp3:((temp1<temp2)?temp1:temp2);
        }
    /*多于3点的情形,用分治法*/
    left=Nearest(points,n/2);      /*递归求解*/
    right=Nearest(&points[n/2],n-n/2);
    d=left<right?left:right;
    /*综合中间带求得最小距离*/
    nearest=d;
    for(i=0;i<n/2;i++)
    /* 通过扫描子集一中每个点检查子集二中与其距离在d之内的
          所有点(最多6个)以完成合并*/
        for(j=n/2;j<n&&(fabs(points[j].y-points[i].y)<d);j++){
            temp=dist(points[i],points[j]);
            nearest=nearest<temp?nearest:temp;
            }
    return nearest;
}

int  compx(const  void*  a,  const  void*  b)  {
    /*实现按x排序*/
    return  ((Point*)a)->x-((Point*)b)->x;
}

int  compy(const  void*  a,  const  void*  b)  {
    /*实现按y排序*/
    return  ((Point*)a)->y-((Point*)b)->y;
}

void main() {
    int i,j=0,numPoints;
    Point  points[MAX_POINTS];
    float result[MAX_TEST];        /*记录结果*/
    for(i=0;i<MAX_TEST;i++)    result[i]=-1;
    printf("请输入数据:/n");
    while(1){                     /*进行多次测试*/
loop:   scanf("%d",  &numPoints);
        if(!numPoints) break;
        if(numPoints<0||numPoints>MAX_POINTS) {
            printf("Error!/n");       /*容错处理*/
            goto loop;
        }
        for(i=0;  i<numPoints;  i++)    /*输入点的数量及点的坐标值*/
            scanf("%f  %f",  &points[i].x,  &points[i].y);
         /*预排序,在使用分治法之前,预先将S中的n个点依其y坐标排序好。*/
        qsort(points, numPoints,  sizeof(Point),  compx);
        qsort(points, numPoints/2,  sizeof(Point), compy);
        qsort(points+numPoints/2,  numPoints-numPoints/2,  sizeof(Point), compy);
        result[j]=Nearest(points, numPoints)/2;
        j++;
        }
    i=0;
    printf("/n最短距离分别为:/n");
    while(result[i]!=-1)    /*输出测试结果*/
            printf("%.2f/n",result[i++]);
}

分治法解决最小套圈问题相关推荐

  1. 【数据结构与算法设计-基础向】C/C++编程练习 - 套圈(分治法解决最近对问题)

    题目: Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at s ...

  2. 分治法解决最大子数组问题

    分治法解决最大子数组问题 参考文章: (1)分治法解决最大子数组问题 (2)https://www.cnblogs.com/Christal-R/p/Christal_R.html (3)https: ...

  3. 分治法解决组合总和问题(leetcode216)

    nums数组中元素是正整数 大问题转换为小问题 思路和分治法解决组合相同,代码也相似 分治法解决组合问题(递归)_m0_52043808的博客-CSDN博客 只不过递归出口时需要判断组合总和是否为n ...

  4. 分治法解决循环赛日程表

    分治法解决循环赛日程表 问题描述 设有n=2^k个运动员要进行羽毛球循环赛,现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次. (2)每个选手一天只能比赛一次. ( ...

  5. 分治法解决矩阵乘法问题

    分治法解决矩阵乘法问题 传统for循环: #include<iostream> #include<cstdio> #include <vector> #includ ...

  6. 分治法解决棋盘覆盖问题

    分治法解决棋盘覆盖问题 问题描述: 在一个2k×2k(k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格.显然,特殊方格在棋盘中出现的位置有4k中情形,因而有4k中不同的棋盘. ...

  7. 分治法解决最近点对问题

    问题 给定平面上n个点,找其中的一对点,使得在n个点的所有点对中,该点对的距离最小.严格地说,最接近点对可能多于1对.为了简单起见,这里只限于找其中的一对. 原理(这段为抄袭https://blog. ...

  8. 蛮力法与分治法解决最近点对问题-详细分析与C++代码实现

    最近点对问题 最近点对问题の目录 最近点对问题 什么是最近点对问题 代码基本框架 蛮力法及其代码 分治法及其代码 一般分治法遇到的特殊情况 如何优化分治法(6点确定与4点确定解法) 优化后分治法(4点 ...

  9. 分治法解决计算凸包问题

    清华大学的邓俊辉老师的<计算几何>公开课中,在计算凸包问题时会遇到极点法和极边法: 极点法是假设所有的点都是凸包上的点,然后根据In-triangle测试,把去除不是极点的点,时间复杂度是 ...

最新文章

  1. python fastapi_Python|介绍一下我的新伙伴fastapi(一)
  2. python读取excel某一行-Python 读取csv的某行
  3. JAVASE——File类
  4. Winform中将WebBrower浏览器控件由IE内核修改为Chrome的WebKit内核
  5. 科大星云诗社动态20201227
  6. PHP的void mixed
  7. ad如何设置pcb板子形状_手把手教你在PCB上添加泪滴
  8. python复制文件的代码_python 复制文件流程
  9. java 悬浮提示框_表格(悬浮框提示)
  10. Python笔记-BeautifulSoup通过查找Id获取元素信息
  11. 2022年计算机二级WPS Office高级应用与设计复习题及答案
  12. HIVE一些字符处理
  13. 管人用人育人留人之道-海潮效应
  14. 以太网rxp rxn txp txn
  15. 运动用什么听歌好,推荐运动骨传导耳机
  16. 车路协同云/边缘云服务平台概要【原创】
  17. 谷歌2019 学术指标发榜:CVPR首次进入Top 10,何恺明论文引用最高!
  18. 彻底关闭烦人的---FF新推荐
  19. IOS —— Crash分析
  20. 无人驾驶汽车系统入门(五)——运动学自行车模型和动力学自行车模型

热门文章

  1. Android关于手机和模拟器的区分
  2. 成都美女网售“叫早”服务:声音甜美淘宝月销第一
  3. 阿里云对象存储OSS前端直传,(配合uView组件使用)
  4. dpkg安装软件流程_Linux软件安装管理之——dpkg与apt-*详解
  5. mupdf源码分析(一)简介
  6. c语言union(c语言union用法)
  7. TOTP - 邮箱或手机号验证码生成与验证
  8. java并发编程-读书笔记
  9. 线程池介绍及创建线程池的4种方式
  10. Java提供的几种线程池总结