求凸包的周长-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)
目录
相关文章
|
7月前
|
计算机视觉 Python
OpenCV轮廓拟合与凸包的讲解与实战应用(附Python源码)
OpenCV轮廓拟合与凸包的讲解与实战应用(附Python源码)
213 0
|
Serverless 计算机视觉 索引
凸包---OpenCV-Python开发指南(28)
凸包---OpenCV-Python开发指南(28)
345 1
凸包---OpenCV-Python开发指南(28)
|
Python
ZZULIOJ-1010,求圆的周长和面积(Python)
ZZULIOJ-1010,求圆的周长和面积(Python)
|
14天前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
13天前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
|
1天前
|
Unix Linux 程序员
[oeasy]python053_学编程为什么从hello_world_开始
视频介绍了“Hello World”程序的由来及其在编程中的重要性。从贝尔实验室诞生的Unix系统和C语言说起,讲述了“Hello World”作为经典示例的起源和流传过程。文章还探讨了C语言对其他编程语言的影响,以及它在系统编程中的地位。最后总结了“Hello World”、print、小括号和双引号等编程概念的来源。
95 80
|
20天前
|
存储 索引 Python
Python编程数据结构的深入理解
深入理解 Python 中的数据结构是提高编程能力的重要途径。通过合理选择和使用数据结构,可以提高程序的效率和质量
131 59
|
13天前
|
小程序 开发者 Python
探索Python编程:从基础到实战
本文将引导你走进Python编程的世界,从基础语法开始,逐步深入到实战项目。我们将一起探讨如何在编程中发挥创意,解决问题,并分享一些实用的技巧和心得。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你提供有价值的参考。让我们一起开启Python编程的探索之旅吧!
38 10
|
17天前
|
机器学习/深度学习 人工智能 Java
Python 语言:强大、灵活与高效的编程之选
本文全面介绍了 Python 编程语言,涵盖其历史、特点、应用领域及核心概念。从 1989 年由 Guido van Rossum 创立至今,Python 凭借简洁的语法和强大的功能,成为数据科学、AI、Web 开发等领域的首选语言。文章还详细探讨了 Python 的语法基础、数据结构、面向对象编程等内容,旨在帮助读者深入了解并有效利用 Python 进行编程。
|
15天前
|
机器学习/深度学习 人工智能 数据挖掘
探索Python编程的奥秘
在数字世界的海洋中,Python如同一艘灵活的帆船,引领着无数探险者穿梭于数据的波涛之中。本文将带你领略Python编程的魅力,从基础语法到实际应用,一步步揭开Python的神秘面纱。
34 12