c++ 找到给定点集的简单闭合路径(Find Simple Closed Path for a given set of points)

给定一组点,将这些点连接起来而不相交

例子: 

输入:points[] = {(0, 3), (1, 1), (2, 2), (4, 4),
                   (0, 0), (1, 2), (3, 1}, {3, 3}};

输出:按以下顺序连接点将
        不造成任何交叉
       {(0, 0), (3, 1), (1, 1), (2, 2), (3, 3),
        (4,4),(1,2),(0,3)}
        
我们强烈建议您最小化浏览器并先自己尝试一下。

这个想法是使用排序。 

通过比较所有点的 y 坐标来找到最底部的点。如果有两个点的 y 值相同,则考虑 x 坐标值较小的点。将最底部的点放在第一个位置。 

考虑剩余的 n-1 个点,并围绕 points[0] 按照极角逆时针顺序排列它们。如果两个点的极角相同,则将最近的点放在最前面。

遍历排序数组(按角度升序排序)产生简单的闭合路径。

如何计算角度? 
一种解决方案是使用三角函数。 
观察:我们不关心角度的实际值。我们只想按角度排序。 
想法:使用方向来比较角度,而无需实际计算它们!

以下是上述想法的实现:

// A C++ program to find simple closed path for n points
// for explanation of orientation()
#include <bits/stdc++.h>
using namespace std;
 
struct Point
{
    int x, y;
};
 
// A global point needed for  sorting points with reference
// to the first point. Used in compare function of qsort()
Point p0;
 
// A utility function to swap two points
int swap(Point &p1, Point &p2)
{
    Point temp = p1;
    p1 = p2;
    p2 = temp;
}
 
// A utility function to return square of distance between
// p1 and p2
int dist(Point p1, Point p2)
{
    return (p1.x - p2.x)*(p1.x - p2.x) +
           (p1.y - p2.y)*(p1.y - p2.y);
}
 
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are collinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Point p, Point q, Point r)
{
    int val = (q.y - p.y) * (r.x - q.x) -
              (q.x - p.x) * (r.y - q.y);
 
    if (val == 0) return 0;  // collinear
    return (val > 0)? 1: 2; // clockwise or counterclock wise
}
 
// A function used by library function qsort() to sort
//  an array of points with respect to the first point
int compare(const void *vp1, const void *vp2)
{
   Point *p1 = (Point *)vp1;
   Point *p2 = (Point *)vp2;
 
   // Find orientation
   int o = orientation(p0, *p1, *p2);
   if (o == 0)
     return (dist(p0, *p2) >= dist(p0, *p1))? -1 : 1;
 
   return (o == 2)? -1: 1;
}
 
// Prints simple closed path for a set of n points.
void printClosedPath(Point points[], int n)
{
   // Find the bottommost point
   int ymin = points[0].y, min = 0;
   for (int i = 1; i < n; i++)
   {
     int y = points[i].y;
 
     // Pick the bottom-most. In case of tie, choose the
     // left most point
     if ((y < ymin) || (ymin == y &&
         points[i].x < points[min].x))
        ymin = points[i].y, min = i;
   }
 
   // Place the bottom-most point at first position
   swap(points[0], points[min]);
 
   // Sort n-1 points with respect to the first point.
   // A point p1 comes before p2 in sorted output if p2
   // has larger polar angle (in counterclockwise
   // direction) than p1
   p0 = points[0];
   qsort(&points[1], n-1, sizeof(Point), compare);
 
   // Now stack has the output points, print contents
   // of stack
   for (int i=0; i<n; i++)
       cout << "(" << points[i].x << ", "
            << points[i].y <<"), ";
}
 
// Driver program to test above functions
int main()
{
    Point points[] = {{0, 3}, {1, 1}, {2, 2}, {4, 4},
                       {0, 0}, {1, 2}, {3, 1}, {3, 3}};
    int n = sizeof(points)/sizeof(points[0]);
    printClosedPath(points, n);
    return 0;
}

输出: 

(0, 0), (3, 1), (1, 1), (2, 2), (3, 3),
(4,4),(1,2),(0,3),
如果我们使用 O(nLogn) 排序算法对点进行排序,则上述解决方案的时间复杂度为 O(n Log n)。
辅助空间: O(1),因为没有占用额外空间。

来源: 
http://www.dcs.gla.ac.uk/~pat/52233/slides/Geometry1x1.pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148141.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

如何在Markdown写文章上传到wordpress保证图片不丢失

如何在Markdown写文章上传到wordpress保证图片不丢失 写文日期,2023-11-16 引文 众所周知markdown是一款nb的笔记软件&#xff0c;本篇文章讲解如何在markdown编写文件后上传至wordpress论坛。并且保证图片不丢失&#xff08;将图片上传至云端而非本地方法&#xff09; 一&…

offsetX、offsetY...

文章目录 offsetX & offsetYclientX & clientYpageX & pageYscreenX & screenYinnerHeight & innerWidthoffsetHeight & offsetWidthoffsetTop & offsetLeftscrollHeight & scrollWidthscrollTop & scrollLeft:与scrollHeight和scrollWidt…

二分查找算法(3) _x的平方根

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 二分查找算法(3) _x的平方根 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 温馨…

《深度学习》—— 卷积神经网络(CNN)的简单介绍和工作原理

文章目录 一、卷积神经网络的简单介绍二、工作原理(还未写完)1.输入层2.卷积层3.池化层4.全连接层5.输出层 一、卷积神经网络的简单介绍 基本概念 定义&#xff1a;卷积神经网络是一种深度学习模型&#xff0c;通常用于图像、视频、语音等信号数据的分类和识别任务。其核心思想…

MIPI协议

MIPI协议 MIPI介绍协议层显示接口&#xff08;Display&#xff09;DBI&#xff08;Display Bus Interface&#xff09;并行传输串行传输 DPI&#xff08;Display Pixel Interface&#xff0c;也称RGB接口&#xff09;DSI&#xff08;Display Serial Interface&#xff09;Appli…

关于使用低版本EPLAN打开高版本项目中的一些常见问题!

目录 1 前言 2 操作方法 2.1 经典版本 2.2 新版本 3 遇到的问题 4 结语 1 前言 在用EPLAN设计图纸时&#xff0c;经常要遇到使用低版本EPLAN打开高版本EPLAN的项目。 EPLAN软件根据操作界面的不同可以分为两种: 1&#xff0c;EPLAN 2.x版本&#xff0c;比如经典的2.9和2…

【Python报错已解决】TypeError: ‘<‘ not supported between instances of ‘str‘ and ‘int‘

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

从规范到实现解读Windows平台如何播放RTSP流

RTSP播放器应用场景 RTSP播放器在视频监控、远程视频会议、网络电视、实时流媒体传输、协同操控相关的智能设备、教育培训以及企业内部通讯与协作等多个领域都有着广泛的应用场景。 1. 视频监控 RTSP直播播放器在视频监控系统中扮演着重要角色。通过RTSP协议&#xff0c;播放…

ComfyUI生成头像

一、下载分享的网盘资源 链接&#xff1a;https://pan.quark.cn/s/706965ed07b5二、解压ComfyUI整合包 找个路径解压整合包&#xff0c;如下图 三、移动model文件 把boleromixPony_v14.safetensors放在Comfyui\ComfyUI\models\checkpoints目录下四、移动lora文件 把从0开始…

【MATLAB源码-第268期】基于simulink的永磁同步电机PMSM双闭环矢量控制系统SVPWM仿真,输出转速响应曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 永磁同步电机&#xff08;PMSM&#xff09;是目前工业领域中广泛使用的一种高效电机&#xff0c;其具有高功率密度、运行效率高、动态响应快等优点。在控制永磁同步电机时&#xff0c;通常采用矢量控制&#xff08;也称为磁场…

MK-1000门控管理系统

MK-1000门控系统简介 1.1 前言 中大型仓库一般由多个仓库组成&#xff0c;每个仓库具有上百个仓库门&#xff0c;人工控制仓库门的开启、闭合等耗时耗力&#xff0c;随着电子信息自动化发展&#xff0c;集中控制仓库门成为现实。本系统可通过网络灵活控制某个仓库的某个门开启、…

萤石云平台接入SVMSPro平台

萤石云平台接入SVMSPro平台 步骤一&#xff1a;进入萤石云官网&#xff1a;https://open.ys7.com/ &#xff0c;点右上角的登陆&#xff0c;填写自己的用户名密码&#xff1b; 步骤二&#xff1a;登陆进去后&#xff0c;开发者服务—>我的账号—>应用信息&#xff0c;在…

nonlocal本质讲解(后篇)——从Nonlocal均值滤波到Transformer的自注意力

Nonlocal均值滤波 → \rightarrow →Nonlocal attention → \rightarrow →Transformer的自注意力 目录 Nonlocal均值滤波Nonlocal attention矩阵表示&#xff0c;这只是为了实现。reshape矩阵运算 相异度矩阵相似度计算1. Gaussian Function&#xff08;高斯函数&#xff09;…

双指针算法介绍与简单运用

双指针算法 一、双指针算法介绍二、常用方法讲解交换力扣&#xff1a;283.移动零大小分类 覆盖力扣&#xff1a;88. 合并两个有序数组C语言 memmove 函数实现 快慢链表的中间结点力扣&#xff1a;141. 环形链表 对撞力扣&#xff1a;9. 回文数力扣&#xff1a;LCR 139. 训练计划…

专业学习|《随机过程》学习笔记(二)(定义、分类及相关过程)

一、随机过程 &#xff08;一&#xff09;随机过程定义 &#xff08;1&#xff09;基本概念 随机过程是随机变量的延伸。 &#xff08;2&#xff09;描述随机过程的方法 &#xff08;3&#xff09;随机过程的分类和举例 &#xff08;4&#xff09;随机过程的数字特征 随机过…

SpringSecurity -- 入门使用

文章目录 什么是 SpringSesurity &#xff1f;细节使用方法 什么是 SpringSesurity &#xff1f; 在我们的开发中&#xff0c;安全还是有些必要的 用 拦截器 和 过滤器 写代码还是比较麻烦。 SpringSecurity 是 SpringBoot 的底层安全默认选型。一般我们需要认证和授权&#xf…

Python文件读取

文件操作的步骤 打开文件读写文件关闭文件 open()打开函数 使用open()可以打开一个已经存在的文件&#xff0c;或者创建一个新文件 open(name,mode,encoding)name:打开文件的文件名&#xff0c;也可以包含具体路径 mode:设置打开文件的模式&#xff1a;只读、写入、追加等…

SpringBoot实战(三十)发送HTTP/HTTPS请求的五种实现方式【下篇】(Okhttp3、RestTemplate、Hutool)

目录 一、五种实现方式对比结果二、Demo接口地址实现方式三、Okhttp3 库实现3.1 简介3.2 Maven依赖3.3 配置文件3.4 配置类3.5 工具类3.6 示例代码3.7 执行结果实现方式四、Spring 的 RestTemplate 实现4.1 简介4.2 Maven依赖4.3 配置文件4.4 配置类4.5 HttpClient 和 RestTemp…

【LLM论文日更】| 俄罗斯套娃嵌入模型

论文&#xff1a;https://proceedings.neurips.cc/paper_files/paper/2022/file/c32319f4868da7613d78af9993100e42-Paper-Conference.pdf代码&#xff1a;GitHub - RAIVNLab/MRL: Code repository for the paper - "Matryoshka Representation Learning"机构&#x…

线程池动态设置线程大小踩坑

在配置线程池核心线程数大小和最大线程数大小后&#xff0c;如果调用线程池setCorePoolSize方法来调整线程池中核心线程的大小&#xff0c;需要特别注意&#xff0c;可能踩坑&#xff0c;说不定增加了线程让你的程序性能更差。 ThreadPoolExecutor有提供一个动态变更线程池核心…