分治法求解最近对问题(c++)
|
#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++)的更多相关文章
- [C++] 分治法之棋盘覆盖、循环赛日程表
一.分治的基本思想 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 对于一个规模为 n 的问题,若问题可以容易地解决,则直接解决,否则将其分解为 k 个规模较小的子 ...
- Java算法——分治法
一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简 ...
- 分治法避免定义多个递归函数,应该使用ResultType
总结:对二叉树应用分治法时,应避免定义多个递归函数,当出现需要递归求解多种的结果时,尽量使用ResultType来让一次递归返回多种结果. 题目:Binary Tree Maximum Path Su ...
- 分治法(一)(zt)
这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它 ...
- p1257 平面上最接近点对---(分治法)
首先就是一维最接近点的情况... #include<iostream> #include<cstdio> #include<cstring> #include< ...
- 分治法及其python实现例子
在前面的排序算法学习中,归并排序和快速排序就是用的分治法,分治法作为三大算法之一的,有非常多的应用例子. 分治法概念 将一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题-- ...
- 分治法 - Divide and Conquer
在计算机科学中,分治法是一种很重要的算法.分治法即『分而治之』,把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的 ...
- poj 3714 Raid【(暴力+剪枝) || (分治法+剪枝)】
题目: http://poj.org/problem?id=3714 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27048#prob ...
- python编写PAT 1007 Maximum Subsequence Sum(暴力 分治法 动态规划)
python编写PAT甲级 1007 Maximum Subsequence Sum wenzongxiao1996 2019.4.3 题目 Given a sequence of K integer ...
随机推荐
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- 【调侃】IOC前世今生
前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...
- BootStrap_02之全局样式及组件
1.BootStrap指定的四种屏幕尺寸: ①超大PC屏幕--lg(large):w>=1200px: ②中等PC屏幕--md(medium):1200px>w>=992px: ③P ...
- 在ubuntu16.10 PHP测试连接MySQL中出现Call to undefined function: mysql_connect()
1.问题: 测试php7.0 链接mysql数据库的时候发生错误: Fatal error: Uncaught Error: Call to undefined function mysqli_con ...
- VICA 架构设计(1)
本文记录最近完成的一个通用实时通信客户端的架构. 背景 我们公司是做税务相关的软件,有针对大客户 MIS 系统,也有针对中小客户的 SaaS 平台.这些系统虽然都是 B/S 的,但是也需要使用 A ...
- Android之DOM解析XML
一.DOM解析方法介绍 DOM是基于树形结构的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树,检索所需数据.分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息 ...
- Git快速入门
如果你不想看长篇的Git教程,想快速了解Git的使用,那么本文可能会对你入门Git有所帮助.由于笔者用的是Windows系统,所以本文只写Git在Windows上的使用. 一.Git安装 去Git官网 ...
- Spark-shell和Spark-Submit的使用
Spark-shell有两种使用方式: 1:直接Spark-shell 会启动一个SparkSubmit进程来模拟Spark运行环境,是一个单机版的. 2:Spark-shell --master S ...
- 使用win10远程控制ubuntu16.04
使用win10远程控制ubuntu16.04,网上很多需要安装xfce桌面的.今天介绍一下,不需要安装其他桌面,使用Ubuntu16.04自带桌面,漂亮美观. Ubuntu16.04端: 1.打开终端 ...
- Linux系统中用DNW向ARM开发板下载程序
在Linux下通过dnw来给开发板发送程序.包括驱动程序代码:secbulk.c,应用程序代码:dnw.c.只能运行在32位系统上,在64位系统上提示错误:DNW download Data size ...