Week 01 ~ 04 : 알고리즘 문제 풀이

파이썬 백준 8983 사냥꾼

정글러 2021. 11. 12. 12:04
import sys  
input = sys.stdin.readline
from bisect import bisect_left

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

line.sort()
count = 0
for i in range(n) :
    x, y = map(int, input().split())
    if not y > l :
        if x <= line[0] :
            if line[0] - x <= l - y :
                count = count + 1
        elif x >= line[-1] :
            if x - line[-1] <= l - y :
                count = count + 1
        else :    
            a = bisect_left(line, x)
            if min(x - line[a-1], line[a] - x) <= l - y :
                count = count + 1
print(count)

m과 n이 크기 때문에, n개의 모든 동물에 대해 사수 하나하나에 찔러보면 시간초과가 날 것이다.
x좌표가 동물에 가장 가까운 사수가 안닿는다면 나머지 더 먼 다른 사수들은 당연히 안 닿을 것이니,
이분탐색으로 각각의 동물에 대해 x좌표가 가장 가까운 사수만 list에서 찾아 비교해주면 빠르게 찾을 수 있다.
리스트의 가장 가까운 원소를 찾아가는 이분탐색은 1920 수 찾기에서 이미 구현했으니 구현은 생략하고,
bisect라는 함수가 있대서 이걸 썼다.

이분탐색이 단순탐색보단 빨라도 시간을 쓰긴 쓰므로, 무작정 동물 수만큼 쓰기보단 한번 거르는 것이 빠르다.
최좌측보다도 왼쪽 동물, 최우측보다도 오른쪽 동물, y가 L보다 먼 동물은 예외처리를 한 뒤 탐색을 돌렸다.

입력이 많아서 그런지 첫 채점때 무려 4464ms가 나왔는데, 평소엔 안쓰던 sys.stdin.readline을 쓰니 324ms가 나왔다.
이게 이렇게까지 차이가 나는구나...

4등 머임
역시 남이 구현해둔 함수를 이용해야 빠르고 편하다는 교훈