Untitled

 avatar
unknown
python
a year ago
3.1 kB
1
Indexable
from time import time


class Skyscraper:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"x: {self.x} y: {self.y}"


def solution():
    n = int(input())
    x, y = [int(i) for i in input().split()]
    viewpoint = Skyscraper(x, y)
    skyscrapers = []
    for _ in range(n - 1):
        x, y = [int(i) for i in input().split()]
        skyscrapers.append(Skyscraper(x, y))

    obstacles = get_state(viewpoint, skyscrapers)
    visible = count_visible(obstacles)
    to_break = []
    while count_visible(obstacles) != n - 1:
        local_to_break = []
        for obstacle in obstacles:
            if obstacle and len(obstacle) < obstacles.count(obstacle): # сколько надо снести < сколько мы получим
                for obs in obstacle:
                    local_to_break.append(obs)
                    skyscrapers[obs] = None

                break
        else:
            return visible, to_break

        obstacles = get_state(viewpoint, skyscrapers)
        new_visible = count_visible(obstacles)
        if visible < new_visible:
            visible = new_visible
            to_break.extend(local_to_break)

    return visible, to_break


def get_state(viewpoint, skyscrapers):
    obstacles = []
    for i in range(len(skyscrapers)):
        if skyscrapers[i] is not None:
            i_obstacles = [skyscrapers.index(obs) for obs in get_obstacles(viewpoint, skyscrapers[i], skyscrapers[:i])]
            obstacles.append(i_obstacles)
        obstacles.append([])

    return obstacles


def is_intersect(x1, y1, x2, y2, x3, y3, x4, y4):
    y4 -= 0.0001 # !!!СМОТРЕТЬ ИЗ УСЛОВИЯ. Оставить если в условии "по внутренним точкам"
    if ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)) == 0:
        print((x1, y1, x2, y2, x3, y3, x4, y4))
    ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))
    ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))

    return 0 <= ua <= 1 and 0 <= ub <= 1


def is_intersect_with_skyscraper(viewpoint: Skyscraper, skyscraper_to_see: Skyscraper, skyscraper_obstacle: Skyscraper):
    cond = is_intersect(viewpoint.x, viewpoint.y, skyscraper_to_see.x, skyscraper_to_see.y, skyscraper_obstacle.x, 0,
                        skyscraper_obstacle.x, skyscraper_obstacle.y)
    return cond


def get_obstacles(viewpoint: Skyscraper, skyscraper: Skyscraper, skyscrapers: list[Skyscraper]):
    obstacles = []

    for obstacle in skyscrapers:
        if obstacle is None:
            continue
        if is_intersect_with_skyscraper(viewpoint, skyscraper, obstacle):
            obstacles.append(obstacle)

    return obstacles


def count_visible(obstacles):
    return sum(1 for obs in obstacles if not obs)


def main():
    s = time()

    t = int(input())

    for _ in range(t):
        ans = solution()[-1]
        print(len(ans))
        print(*[a + 2 for a in ans])

    e = time()
    print(e - s)


main()
Leave a Comment