[python] BOJ 8983 사냥꾼

Jin Lee·2021년 12월 28일
0

백준

목록 보기
4/7

[intro]

사냥꾼이라는 단어에 현혹되지 마십시오. 당신은 사냥감입니다.

생사의 기로에 놓인 한마리 토끼가 되어 보는게 문제의 핵심 키

⇒ 동물을 기준으로 내가 죽을 수 있는 범위의 x 좌표에 사대가 있는지를 확인하고, 그 사대에서 나를 맞출 수 있는 사격범위안에 들어오는지 계산한다. 만약 그 범위 안에 내가 있다면 나는 죽는다.

⇒ 왜 동물을 기준으로 생각해야 하는가?

동물을 기준으로 생각 : 100,000 log 100,000 = 500000 (동물의 수에 대한 이분탐색의 시간복잡도)

사대기준으로 생각 : 100,000 100,000 = 10,000,000,000 (사대의 수 동물의 수의 시간복잡도)

[코드 설명]

사대를 확인하는 과정에서 이분탐색을 사용하기 때문에 정렬 해준 다음 헌팅 함수에 유효한 start_x 범위와 end_x 범위를 찾는다.

⇒ 동물의 y 좌표가 총의 사정거리보다 크다면 잡을 수 없는 동물이므로 다음 좌표를 본다.

hunting 함수는 동물의 x,y좌표로 계산된 유효 사대의 시작과 끝을 받아 해당 범위 내에 사대가 존재하는지를 확인한다.

사대는 start ≤ candidate ≤ end 내에 존재해야 하며 이 범위에 존재하지 않는다면 사대는 없는 것, candidate의 초기값은 이 문제에서 들어올 수 없는 최댓값으로 설정해야 하므로 20억 1(10억 + 10억 + 1)로 설정한다.

리턴하는 값은 사대가 존재한다면 True, 존재하지 않는다면 False 이다. 이 과정에서 이분탐색이 사용된다.

def hunting(start, end):
    candidate = 2000000001
    left = 0
    right = len(hunting_zone) - 1
    while left <= right:
        mid = (left + right) // 2
        if start > hunting_zone[mid]:
            left = mid + 1

        else:
            right = mid - 1
            if candidate > hunting_zone[mid]:
                candidate = hunting_zone[mid]

    return candidate <= end


n, m , l = map(int, input().split())

hunting_zone = list(map(int,input().split()))
hunting_zone.sort()
death = 0
for i in range(m):
    animal_x, animal_y = map(int, input().split())

    if animal_y <= l:
        start_x = animal_x - (l - animal_y)
        end_x = animal_x + (l - animal_y)

        if hunting(start_x, end_x):
            death = death + 1

print(death)
profile
깃허브 : https://github.com/jinlee9270

0개의 댓글