Bootstrap

蓝桥3529 太阳 | 几何计算+自定义排序

题目传送门
·


这个题目的处理方法是利用相似三角形的思路,将线段的两个端点按照投影排序(首先将“太阳”转换到坐标系原点),先遍历端点,将左端点加入set,每次找到最小左端点并记录,当遍历到右端点时从set中删除对应的左端点。最后统计记录的端点数即可。



n,X,Y = map(int,input().split())

# 线段端点类
class P:
    def __init__(self, x, y, c):
        self.x = x
        self.y = y
        self.c = c

    def __eq__(self, other):
        return 1 * other.y * self.x == 1 * other.x * self.y

    def __lt__(self, other):
        a = (1 * other.y * self.x)
        b = (1 * other.x * self.y)
        return  a < b

vec = []
islighted = [False]*(n+1) # 线段是否被太阳照亮

for i in range(1, n+1):
    x, y, l = map(int, input().split())
    vec.append(P(x-X, Y-y, i))        # 左端点,太阳一定比线段高
    vec.append(P(x-X+l, Y-y, -i))     # 右端点

vec.sort()

st = set()
edge = P(-1,1,0)

for it in vec:
    if it != edge:
        if st:
            islighted[min(st)[1]] = True
        edge = it
    if it.c > 0:
        st.add((it.y, it.c))       # 是左端点,加入列表
    else:
        st.remove((it.y, -it.c))    # 到达右端点,停止考虑该线段

res = sum(islighted)
print(res)

END✨


;