算法训练营--凸包

作者: 拜仁的月饼 | 来源:发表于2019-06-11 22:39 被阅读0次

描述

给定n个二维平面上的点,求他们的凸包。

输入

第一行包含一个正整数n。

接下来n行,每行包含两个整数x,y,表示一个点的坐标。

输出

令所有在凸包极边上的点依次为p1,p2,...,pm(序号),其中m表示点的个数,请输出以下整数:

(p1 × p2 × ... × pm × m) mod (n + 1)

样例1输入

10
7 9
-8 -1
-3 -1
1 4
-3 9
6 -4
7 5
6 6
-6 10
0 8

样例1输出

7

样例1解释

image

所以答案为(9 × 2 × 6 × 7 × 1 × 5) % (10 + 1) = 7

样例2

请查看下发文件内的sample2_input.txt和sample2_output.txt。

限制

3 ≤ n ≤ 10^5

所有点的坐标均为范围(-10^5, 105)内的整数,且没有重合点。每个点在(-105, 10^5) × (-10^5, 10^5)范围内均匀随机选取

极边上的所有点均被视作极点,故在输出时亦不得遗漏

时间:4 sec

空间:512 MB

代码实现

#!/usr/bin/env pypy3
# -*- coding: utf-8 -*-

# ================= 代码实现开始 =================
class Pwo: # "Pwo"的意思是"Points with order"(有顺序的点)
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.i = 0 # 用i来代表顺序
# --------------小小分割线-------------------
def orientation(p, q, r):
    val = (q.y - p.y)*(r.x - q.x) - (r.y - q.y)*(q.x - p.x) # 用斜率比较
    a = 0 # 最终返回值是这个
    if val == 0: # 如果点1、2的斜率和点23、斜率相等
        a = 0 #那么a = 0,证明三点一线
    elif val > 0:
        a = 1 # 顺时针
    else:
        a = 2 # 逆时针

    return a
# --------------小小分割线-------------------
def convex(points, n):
    if n < 3: # 必须比三点多才可能有凸包
        return None

    hull = list() # 初始化一个空列表,返回值也是这个
    # 寻找最左的点
    leftmost = 0 #初始化一个点
    for i in range(n):
        if points[i].x < points[leftmost].x: # 如果有一个点比点0还要小
            leftmost = i # 那么第i个就是最左的点

    p = leftmost # p是上一个点
    q = 0 # 用在循环中
    while (3 > 1):
        hull.append(points[p]) #每次循环开始的时候,将点p装入列表hull中
        q = (p + 1) % n # q是任意点
        for j in range(n): # 遍历所有点,找凸包点:
            if orientation(points[p], points[j], points[q]) == 2: # 如果相对于p点是最逆时针旋转的
                q = j # 更新q值为j
        p = q # 用q值更新p值
        if p == leftmost: #如果转到原点了
            break #跳出循环

    return hull #将列表返回
# ================= 代码实现结束 =================
if __name__ == '__main__':
    n = int(input())
    a = [Pwo(0, 0) for i in range(n)]

    for i in range(n):
        a[i].x, a[i].y = map(int, input().split())
        a[i].i = i + 1

    h = convex(a, n)
    m = len(h)
    a = m
    for j in range(m):
        a *= h[j].i

    ans = a % (n + 1)
    print(ans)

References

[1]Convex Hull -- GeeksforGeeks
[2]How to check if two given line segments intersect? -- GeeksforGeeks](https://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/)

相关文章

  • 算法训练营--凸包

    描述 给定n个二维平面上的点,求他们的凸包。 输入 第一行包含一个正整数n。 接下来n行,每行包含两个整数x,y,...

  • 算法复习-geometric algo

    convex hull 凸包-video25&video26 凸包算法剖析https://cyw3.github....

  • 凸包算法

    R版本 python版本

  • 凸包算法

    凸包点集的性质 凸包点集中,取出相邻的两个点所构成的边一定能将所有点分割在一边,而另一边并无任何点。 若我们可以按...

  • Python3 趣味系列题8 ------ 凸包动态绘制

    本文介绍利用Graham Scan算法获得凸包(平面凸包),并动态展示凸包的形成过程。下面用比较通俗的语言,介绍下...

  • 凸包

    凸包最常用的凸包算法是Graham扫描法和Jarvis步进法Graham's Scan法这个算法是由数学大师葛立恒...

  • 提取平面点云的轮廓

    一. 基于凸包的凹点挖掘算法: 1. 提取点云的凸包 2. 计算凸包每条边的顶点的点密度(即该点 K 个临...

  • Jarvis步进凸包算法

    凸包算法作为计算几何的基础和核心问题足以引起重视.这里给出Jarvis步进算法的Python实现.测试环境是Ubu...

  • 《python算法教程》Day11 - 分治法求解平面凸包问题

    这是《python算法教程》的第11篇读书笔记,笔记主要内容是使用分治法求解凸包。 平面凸包问题简介 在一个平面点...

  • 凸优化笔记2-主要内容

    笔记主要内容 凸集、凸函数、凸优化 凸优化理论 若干算法

网友评论

    本文标题:算法训练营--凸包

    本文链接:https://www.haomeiwen.com/subject/izaffctx.html