求凸包的周长-python

简介: 求凸包的周长-python

题目描述


平面直角坐标系中求一个凸包的周长 C。


输入描述


第一行输入一个 n ,代表测试数据量

接下来 n 行输入 nn 个坐标 (x,y)

1≤n≤5×10^4,∣x∣,∣y∣≤10^4


输出描述


输出 C, 结果保留 6位小数。


输入输出样例


示例 1

输入

1. 4
2. 4 8
3. 4 12
4. 5 9.3
5. 7 8

输出

12.000000

运行限制

  • 最大运行时间:3s
  • 最大运行内存: 256M

思路


核心思想:

凸包算法的基本思路是 旋转扫除,即设定一个参照顶点,逐个旋转到其它所有顶点,并判断这些顶点是否在凸包上。算法做两次扫描,先从最左边的点沿“下凸包”扫描到最右边,再从最右边的点沿“上凸包”扫描到最左边,“上凸包”和“下凸包”合起来就是完整的凸包。

具体过程:

1.我们把所有的点按照横坐标 x 从小到大进行排序,如果 x 相同,按 y 从小到大排序。并删除重复的点。

2.我们找到最左边的点,p0一定在凸包上,从左往右扫描,如果发现新点在凸包“前进”方向的左边,说明在“下凸包”上,把它加入到凸包;如果在右边,说明拐弯了,删除最近加入下凸包的点。继续这个过程,直到检查完所有点。

注:拐弯方向用叉积判断即可。当叉积为<=0时,说明前进的方向在新点的左侧,要删除刚才加入的点,加上我们的新点。

3.再从右往左扫描点,注意我们这里直接将已经排好序的点逆序遍历,叉积的判断代码不变,依旧是左旋(左是相对于前进路线而言)。最后要记得pop出最后一个节点,因为这个节点就是我们一开始的p[0]点,其实不进行这一步也是可以的,因为我们最终通过点的坐标来累加周长,相同的点之间的距离为0,对结果无影响。

4.我们得到了所有的点,只需依次累加两个相邻点之间的距离即可


代码


1. from decimal import *
2. from math import sqrt
3. 
4. class Point:
5.     def __init__(self, x=0, y=0):
6. self.x = x
7. self.y = y
8.     #重写运算符“==”,“+”,“-”,“*”
9.     def __eq__(self, other):
10. return self.x == other.x and self.y == other.y
11.     def __add__(self, other):
12. return Point(self.x + other.x, self.y + other.y)
13.     def __sub__(self, other):
14. return Point(self.x - other.x, self.y - other.y)
15.     def __mul__(self, other):
16. return self.x * other.x + self.y * other.y
17.     #__repr__() 方法是类的实例化对象用来做“自我介绍”的方法,
18.     #默认情况下,它会返回当前对象的“类名+object at+内存地址”,
19.     #而如果对该方法进行重写,可以为其制作自定义的自我描述信息。
20.     def __repr__(self):
21. return str(self.x) + " " + str(self.y)
22. 
23. #通过两个向量计算叉乘
24. def cross(a, b):
25. return a.x * b.y - a.y * b.x
26. #通过三个点计算向量ab和ac的叉乘
27. def clockwise(a, b, c):
28. return cross(b - a, c - a)
29. #计算平方
30. def square(x):
31. return x * x
32. #计算平方和
33. def dis2(a, b):
34. return square(a.x - b.x) + square(a.y - b.y)
35. #计算两点距离
36. def dis(a, b):
37. return sqrt(dis2(a, b))
38. #遍历两次
39. def convex_hull(p):
40.     def cmp(a):
41. return a.x * 100000 + a.y
42.     p = sorted(p, key=cmp)
43.     n = len(p)
44.     stk = []
45.     stk.append(p[0])
46. for i in p[1:]:
47.         while len(stk) > 1 and cross(stk[-1] - stk[-2], i - stk[-2]) <= 0:
48.             del stk[-1]
49.         stk.append(i)
50.     tmp = len(stk)
51. 
52. for i in p[::-1]:
53.         #还是左旋
54.         while len(stk) > tmp and cross(stk[-1] - stk[-2], i - stk[-2]) <= 0:
55.             del stk[-1]
56.         stk.append(i)
57.     stk.pop()
58. return stk
59. 
60. #设置小数点的精度
61. #getcontext().prec = 50
62. 
63. n = int(input())
64. p = [Point() for i in range(n)]
65. for i in p:
66.     i.x, i.y = map(Decimal, input().split())
67. 
68. convex = convex_hull(p)
69. C = 0
70. for i in range(len(convex)):
71.     C += dis(convex[i - 1], convex[i])
72. print("%.6f" % C)
目录
相关文章
|
6月前
|
计算机视觉 Python
OpenCV轮廓拟合与凸包的讲解与实战应用(附Python源码)
OpenCV轮廓拟合与凸包的讲解与实战应用(附Python源码)
179 0
|
Serverless 计算机视觉 索引
凸包---OpenCV-Python开发指南(28)
凸包---OpenCV-Python开发指南(28)
330 1
凸包---OpenCV-Python开发指南(28)
|
Python
ZZULIOJ-1010,求圆的周长和面积(Python)
ZZULIOJ-1010,求圆的周长和面积(Python)
|
10天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
1天前
|
Python
不容错过!Python中图的精妙表示与高效遍历策略,提升你的编程艺术感
本文介绍了Python中图的表示方法及遍历策略。图可通过邻接表或邻接矩阵表示,前者节省空间适合稀疏图,后者便于检查连接但占用更多空间。文章详细展示了邻接表和邻接矩阵的实现,并讲解了深度优先搜索(DFS)和广度优先搜索(BFS)的遍历方法,帮助读者掌握图的基本操作和应用技巧。
13 4
|
1天前
|
设计模式 程序员 数据处理
编程之旅:探索Python中的装饰器
【10月更文挑战第34天】在编程的海洋中,Python这艘航船以其简洁优雅著称。其中,装饰器作为一项高级特性,如同船上的风帆,让代码更加灵活和强大。本文将带你领略装饰器的奥秘,从基础概念到实际应用,一起感受编程之美。
|
3天前
|
存储 人工智能 数据挖掘
从零起步,揭秘Python编程如何带你从新手村迈向高手殿堂
【10月更文挑战第32天】Python,诞生于1991年的高级编程语言,以其简洁明了的语法成为众多程序员的入门首选。从基础的变量类型、控制流到列表、字典等数据结构,再到函数定义与调用及面向对象编程,Python提供了丰富的功能和强大的库支持,适用于Web开发、数据分析、人工智能等多个领域。学习Python不仅是掌握一门语言,更是加入一个充满活力的技术社区,开启探索未知世界的旅程。
13 5
|
1天前
|
机器学习/深度学习 JSON API
Python编程实战:构建一个简单的天气预报应用
Python编程实战:构建一个简单的天气预报应用
10 1
|
1天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
15 2
|
4天前
|
人工智能 数据挖掘 开发者
探索Python编程:从基础到进阶
【10月更文挑战第32天】本文旨在通过浅显易懂的语言,带领读者从零开始学习Python编程。我们将一起探索Python的基础语法,了解如何编写简单的程序,并逐步深入到更复杂的编程概念。文章将通过实际的代码示例,帮助读者加深理解,并在结尾处提供练习题以巩固所学知识。无论你是编程新手还是希望提升编程技能的开发者,这篇文章都将为你的学习之旅提供宝贵的指导和启发。
下一篇
无影云桌面