📜  门| GATE CS 2012 |问题19(1)

📅  最后修改于: 2023-12-03 14:58:19.705000             🧑  作者: Mango

门| GATE CS 2012 |问题19

本题涉及图形学和计算几何,并要求编写程序来解决问题。

题目描述

给出一个带有n个顶点的二维多边形,不保证是凸多边形。你需要找到一个点S,使得所有其他点在这个点的上方,即所有其他点的Y坐标都大于等于S的Y坐标。你需要输出这个点的X坐标。

输入格式

输入的第一行包含一个整数n,表示多边形顶点的数量。随后n行,每行包含两个整数x和y,表示多边形中的一个顶点。

输出格式

输出一行一个整数,表示满足条件的点S的X坐标。

测试数据

输入样例1:

4
1 2
1 4
3 5
6 2

输出样例1:

3

输入样例2:

5
0 0
1 1
2 2
4 4
5 0

输出样例2:

2
题解

题目要求找到一个点S,使得所有其他点在这个点的上方。我们可以通过计算每个点的y坐标来判断是否在点S上方。因此,我们需要找到多边形中y坐标最大的点,即使得所有其他点的y坐标都小于等于它。

如果我们考虑到点要在多边形内,S的x坐标必须在多边形的边界之间。我们可以遍历所有边界,检查顶点是否满足条件。如果顶点的y坐标小于等于S的y坐标,并且S的x坐标在线段的两个顶点之间,那么该线段就是一个候选的边界。

但是,这种方法会有一个问题:如果所有顶点都在线段的同一侧,我们无法找到合适的线段,并且算法会失败。这种情况下需要特殊考虑。

幸运的是,有另一种方法来解决这个问题。我们可以将整个多边形旋转180度,这将使x轴的正方向指向原来的下方。因此,我们现在需要找到y坐标的最小值(即最上面的点)。使用类似的方法,我们可以找到多边形的边缘,其中y坐标大于等于最上面的点的y坐标,并且其x坐标在线段的两个顶点之间。这个边界的交集是S可能存在的区域。

我们可以通过检查每个顶点是否在这个区域内来确定S的x坐标。

代码

下面是解决该问题的Python代码示例:

from typing import List

def find_s_point(n:int, points:List[List[int]]) -> int:
    max_y = float("-inf")
    for x, y in points:
        max_y = max(max_y, y)

    candidates = []
    for i in range(n):
        x1, y1 = points[i]
        x2, y2 = points[(i+1)%n]
        if y1 != y2:
            if y1 < y2:
                ymin, ymax = y1, y2
            else:
                ymin, ymax = y2, y1

            if ymax <= max_y:
                candidates.append((x1, xmax + (max_y - ymax) * (x2 - x1) / (y2 - y1)))

    min_x = float("inf")
    for x, y in candidates:
        if y >= max_y:
            min_x = min(min_x, x)

    return min_x

在这个函数中,我们首先找到y坐标的最大值。然后,我们遍历多边形的边界,找到所有可能的边缘候选者。我们检查每个候选线段是否在坐标系下半部分,并且符合条件。如果是这样,则我们将它添加到候选列表中。

最后,我们根据候选列表和最大y坐标确定S的x坐标。