poj2187凸包

2024-06-16 05:38
文章标签 凸包 poj2187

本文主要是介绍poj2187凸包,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天复习了一下凸包,感觉对于它的理解又加深了,凸包注意的有几点:1基准点在最下面的最左边(习惯性的,注意不只是最下面)2,另外零要重新定义,不再只是一个数,而是一个范围,那么此时对于判零的一系列操作就要注意了,什么时候为右端点,什么时候为左端点,什么时候要进行判零操作等等,3叉乘,要注意与qsort的结合,不要搞混了。

下面是这题的代码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <cmath>
using namespace std;
#define maxn 50000
#define zero 1e-8
struct Point
{int x;int y;
}node[maxn];int n;
inline int Distance(const Point ,const Point );
int cmp(const void *,const void*);
int CJ(const Point,const Point,const Point);
bool Is_zero(double );
void TB(int );int main()
{scanf("%d",&n);int i,pivot;int below=maxn;for(i=0;i<n;i++){scanf("%d%d",&node[i].x,&node[i].y);if(node[i].y<below){below=node[i].y;pivot=i;}}for(i=0;i<n;i++){if(node[i].y==node[pivot].y && node[i].x<node[pivot].x)pivot=i;}	Point temp;temp=node[0];node[0]=node[pivot];node[pivot]=temp;qsort(node+1,n-1,sizeof(Point),cmp);for(i=0;i<n;i++)cout << node[i].x << " " << node[i].y << endl;int k=1;for(i=2;i<n;i++){if(Is_zero(double(CJ(node[0],node[k],node[i])))){if(Distance(node[0],node[k])<Distance(node[0],node[i]))node[k]=node[i];}elsenode[++k]=node[i];}TB(k+1);return 0;
}
inline int Distance(const Point a,Point b){return (b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y);
}int cmp(const void *p,const void*q){return CJ(node[0],*((Point*)p),*((Point *)q))>zero?1:-1;
}
int CJ(const Point s,const Point p,const Point q) //sq叉乘sp
{return (q.x-s.x)*(p.y-s.y)-(q.y-s.y)*(p.x-s.x);
}bool Is_zero(double x){return fabs(x)<=zero;
}
void TB(int m){node[m]=node[0];int i,j,k=2;for(i=3;i<=m;i++){while(CJ(node[k],node[k-1],node[i])<-zero)k--;node[++k]=node[i];}int temp=-maxn;int xpivot,ypivot;int ans;for(i=0;i<k;i++){for(j=0;j<k;j++){ans=Distance(node[i],node[j]);if(ans>temp){temp=ans;xpivot=i;ypivot=j;}}}printf("%d\n",(node[xpivot].x-node[ypivot].x) * (node[xpivot].x-node[ypivot].x) + (node[xpivot].y-node[ypivot].y) * (node[xpivot].y-node[ypivot].y)  );
}

里面包含了凸包的模版,好好理解,特别是void TB(int m)中的while循环,注意与if的差别,以及主函数中的for循环,都是利用了:满足条件则进,不满足则退的思想,当然这不够准确,还是要自己慢慢思考才能理解....

这篇关于poj2187凸包的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1065594

相关文章

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

poj 2187 凸包or旋转qia壳法

题意: 给n(50000)个点,求这些点与点之间距离最大的距离。 解析: 先求凸包然后暴力。 或者旋转卡壳大法。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <s

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

HDU 1392 HDU 1348 凸包

求凸包的周长,  注意n=1 , 2时特殊情况 int cmp(double x){if(fabs(x) < 1e-8) return 0 ;if(x > 0) return 1 ;return -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}frien

【UVA】10652-Board Wrapping(凸包问题)

又增加了2个模板。 #include <iostream>#include <cstdlib>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <stack>#include <algorithm>usi

百度之星初赛1006(计算几何:能包含凸包的最小矩形面积)

矩形面积    Accepts: 717    Submissions: 1619  Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些

OpenCV结构分析与形状描述符(8)点集凸包计算函数convexHull()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 查找一个点集的凸包。 函数 cv::convexHull 使用斯克拉斯基算法(Sklansky’s algorithm)来查找一个二维点集的凸包,在当前实现中该算法的时间复杂度为 O(N logN)。 函数 cv::convexHull 是

OpenCV结构分析与形状描述符(9)检测轮廓相对于其凸包的凹陷缺陷函数convexityDefects()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 查找一个轮廓的凸性缺陷。 下图显示了一个手部轮廓的凸性缺陷: convexityDefects 是 OpenCV 库中的一个函数,用于检测轮廓相对于其凸包的凹陷缺陷。这个函数可以帮助识别轮廓中的凹进去的部分,通常被用来分析手部或其他物体的形状

分治算法与凸包问题

1. 什么是凸包问题? 凸包问题是计算几何中的经典问题。给定二维平面上的点集,凸包是一个最小的凸多边形,它包含了点集中所有的点。你可以把凸包想象成一根松紧带将所有点紧紧包裹住的样子,凸包的边缘仅沿着最外面的点延伸。 2. 分治法简介 分治算法是解决复杂问题的强大策略,它的思想是将问题分解为多个子问题,分别解决这些子问题后再合并得到最终解。凸包问题可以通过分治算法高效地解决,时间复杂度可以达到

多边形快速凸包算法(Melkman‘s Algorithm)

前言 平面点集的凸包算法一文介绍了如何计算平面点集或者任意多边形的凸包。对于随机的平面点集,Graham scan和Andraw's 单调链算法已经是最快的算法了。但是对于没有自相交的封闭的简单多边形,存在线性复杂度的算法。下面介绍这一优雅高效的算法。 一般的2D凸包算法,首先将点进行排序(时间复杂度),然后利用栈操作在O(n)的时间复杂度内计算凸包。初始的排序决定了最终的时间复杂度。但是本文