#include"stdafx.h"
#include<iostream>
#include<cmath>
#define TRUE 1
#define FALSE 0
using namespace std;
typedef struct Node//坐标点
{
 double x;
 double y;
}Node;  
typedef struct List
{
 Node* data;      //点
 int count;      //点的个数
}List;
typedef struct CloseNode
{
 Node a;
 Node b;     //计算距离的两个点
 double space;     //距离平方
}CloseNode;
int n;     //点的数目
//输入各点到List中
void create(List &L)
{
 cout << "请输入平面上点的数目:\n";
 cin >> n;
 L.count = n;
 L.data = new Node[L.count];      //动态空间分配
 cout << "输入各点坐标 :x_y):" << endl;
 for (int i = 0; i<L.count; ++i)
  cin >> L.data[i].x >> L.data[i].y;
}
//求距离的平方
double square(Node a, Node b)
{
 return ((a.x - b.x)*(a.x - b.x)) + ((a.y - b.y)*(a.y - b.y));
}
//冒泡排序
void BubbleSort(Node r[], int length)
{
 int change, n;
 n = length; change = TRUE;
 double b, c;
 for (int i = 0; i<n - 1 && change; ++i)
 {
  change = FALSE;
  for (int j = 0; j<n - i - 1; ++j)
  {
   if (r[j].x>r[j + 1].x)
   {
    b = r[j].x; c = r[j].y;
    r[j].x = r[j + 1].x; r[j].y = r[j + 1].y;
    r[j + 1].x = b; r[j + 1].y = c;
    change = TRUE;
   }
  }
 }
}
//分治法中先将坐标按X轴从小到大的顺序排列
void paixu(List L)
{
 BubbleSort(L.data, L.count);   //调用冒泡排序
}
//左右各距中线d的区域的最近对算法
void middle(const List & L, CloseNode &cnode, int mid, double midX)
{
 int i, j;    //分别表示中线左边,右边的点
 double d = sqrt(cnode.space);
 i = mid;
 while (i >= 0 && L.data[i].x >= (midX - d))    //在左边的d区域内
 {
  j = mid;
  while (L.data[++j].x <= (midX + d) && j <= L.count)    //在右边的d区域内
  {
   if (L.data[j].y<(L.data[i].y - d) || L.data[j].y>(L.data[i].y + d))   //判断纵坐标是否在左边某固定点的2d区域内
    continue;
   double space = square(L.data[i], L.data[j]);
   if (cnode.space>space)    //在满足条件的区域内依次判断
   {
    cnode.a = L.data[i];
    cnode.b = L.data[j];
    cnode.space = space;
   }
  }
  --i;
 }
}
//分治法求最近对
void DivideConquer(const List &L, CloseNode &closenode, int begin, int end)
{
 if (begin != end)
 {
  int mid = (begin + end) / 2;     //排列后的中间的那个点
  double midX = L.data[mid].x;
  DivideConquer(L, closenode, begin, mid);      //继续在左半边用分治法求最近对
  DivideConquer(L, closenode, mid + 1, end);      //继续在右半边用分治法求最近对
  middle(L, closenode, mid, midX);               //判断左右各距中线d的区域,是否有最近对
 }
}
void main()
{
 //初始化
 List list;
 CloseNode closenode;
 closenode.space = 10000;    
 create(list);    
 cout << "各点坐标为:" << endl;
 for (int i = 0; i<list.count; ++i)
  cout << "X=" << list.data[i].x << "   Y=" << list.data[i].y << "\n";
 cout << "用分治法求最近对:" << endl;
 paixu(list);
 cout << "经过排序后的各点:" << endl;
 for (int j = 0; j<list.count; ++j)
  cout << "X=" << list.data[j].x << "   Y=" << list.data[j].y << "\n";
 DivideConquer(list, closenode, 0, list.count - 1);
 cout << "最近对为点 (" << closenode.a.x << "," << closenode.a.y << ")和点(" << closenode.b.x << "," << closenode.b.y << ")\n" << "最近距离为: " << sqrt(closenode.space) << endl;
}
 

分治法求解最近对问题(c++)的更多相关文章

  1. [C++] 分治法之棋盘覆盖、循环赛日程表

    一.分治的基本思想 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 对于一个规模为 n 的问题,若问题可以容易地解决,则直接解决,否则将其分解为 k 个规模较小的子 ...

  2. Java算法——分治法

         一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简 ...

  3. 分治法避免定义多个递归函数,应该使用ResultType

    总结:对二叉树应用分治法时,应避免定义多个递归函数,当出现需要递归求解多种的结果时,尽量使用ResultType来让一次递归返回多种结果. 题目:Binary Tree Maximum Path Su ...

  4. 分治法(一)(zt)

    这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它 ...

  5. p1257 平面上最接近点对---(分治法)

    首先就是一维最接近点的情况... #include<iostream> #include<cstdio> #include<cstring> #include< ...

  6. 分治法及其python实现例子

    在前面的排序算法学习中,归并排序和快速排序就是用的分治法,分治法作为三大算法之一的,有非常多的应用例子. 分治法概念 将一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题-- ...

  7. 分治法 - Divide and Conquer

    在计算机科学中,分治法是一种很重要的算法.分治法即『分而治之』,把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的 ...

  8. poj 3714 Raid【(暴力+剪枝) || (分治法+剪枝)】

    题目:  http://poj.org/problem?id=3714 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27048#prob ...

  9. python编写PAT 1007 Maximum Subsequence Sum(暴力 分治法 动态规划)

    python编写PAT甲级 1007 Maximum Subsequence Sum wenzongxiao1996 2019.4.3 题目 Given a sequence of K integer ...

随机推荐

  1. 【社工】NodeJS 应用仓库钓鱼

    前言 城堡总是从内部攻破的.再强大的系统,也得通过人来控制.如果将入侵直接从人这个环节发起,那么再坚固的防线,也都成为摆设. 下面分享一个例子,利用应用仓库,渗透到开发人员的系统中. 应用仓库 应用仓 ...

  2. rnandroid环境搭建

    react-native 环境搭建具体步骤这个大家已经玩烂了,这个主要是记录下来自己做win7系统遇到的坑 1.com.android.ddmlib.installexception 遇到这个问题,在 ...

  3. input[tyle="file"]样式修改及上传文件名显示

    默认的上传样式我们总觉得不太好看,根据需求总想改成和上下结构统一的风格…… 实现方法和思路: 1.在input元素外加a超链接标签 2.给a标签设置按钮样式 3.设置input[type='file' ...

  4. angular2系列教程(七)Injectable、Promise、Interface、使用服务

    今天我们要讲的ng2的service这个概念,和ng1一样,service通常用于发送http请求,但其实你可以在里面封装任何你想封装的方法,有时候控制器之间的通讯也是依靠service来完成的,让我 ...

  5. iOS开发之再探多线程编程:Grand Central Dispatch详解

    Swift3.0相关代码已在github上更新.之前关于iOS开发多线程的内容发布过一篇博客,其中介绍了NSThread.操作队列以及GCD,介绍的不够深入.今天就以GCD为主题来全面的总结一下GCD ...

  6. 在Windows上编译和调试CoreCLR

    生成CoreCLR - Windows篇 本文的唯一目的就是让你运行Hello World 运行环境 Window 7+ Visual studio 2015 确保C++ 工具已经被安装,默认是不安装 ...

  7. js学习之类型识别

    用来判别类型的方法有好多,整理了一下4种方法,平时用的时候,在不同情景下,还是要结合着使用的. 方法一 typeof:可以识别标准类型,除了Null:不能识别具体的对象类型,除了Function &l ...

  8. C# 实时折线图,波形图

    此Demo是采用VS自带的Chart图表控件,制作实时动态显示的折线图,和波形图. 涉及到知识如下: Chart 控件,功能强大,可以绘制柱状图,折线图,波形图,饼状图,大大简化了对图的开发与定制. ...

  9. ES6之let命令详解

    let与块级作用域 { var foo='foo'; let bar='bar'; } console.log(foo,'var'); //foo varconsole.log(bar ,'bar') ...

  10. 转:MSSQL还原单mdf文件报1813错误

    原文地址:http://www.cnblogs.com/clownkings/p/4950865.html 解决办法: 1.首先要备份好mdf文件,如果他没了经理非吃了你不可.都不吐骨头的. 2.在数 ...