본문 바로가기

알고리즘

백준 8983 사냥꾼

728x90

백준 8983 사냥꾼

https://www.acmicpc.net/problem/8983

 

8983번: 사냥꾼

입력의 첫 줄에는 사대의 수 M (1 ≤ M ≤ 100,000), 동물의 수 N (1 ≤ N ≤ 100,000), 사정거리 L (1 ≤ L ≤ 1,000,000,000)이 빈칸을 사이에 두고 주어진다. 두 번째 줄에는 사대의 위치를 나타내는 M개의 x-좌

www.acmicpc.net

 

처음 이 문제를 봤을 때, 풀이 방법을 아예 모르겠어서 막막했었다.

여러번 반복해서 보니, 신기하게 풀린다.

 

접근방법

사대를 움직여 해당 동물을 죽일 수 있는지 살펴본다!

기준을 사대로 잡아야 한다!!

 

풀이

사대 길이와 |x-a| + b 길이 비교해 해당거리 내에 있으면 동물을 잡을 수 있고

없으면, 사대 위치를 조정해야 한다.

 

사대 위치는 무조건 사대 리스트 안에서만 움직일 수 있다.

즉, 사대 위치는 6,1,4,9 범위 내에 있을 수 있으므로 index로 조절해야 한다.

사대 위치는 정렬 시켜놔야 left ,right 조절할 수 있으므로 정렬한다.

 

그리고 단순하게 동물의 x축 위치가 사대보다 크면 사대를 오른쪽으로 이동

반대로 동물의 x축 위치가 사대의  x축 위치보다 작으면 사대를 왼쪽으로 이동 시켰다.

 

나의 코드

import sys
input = sys.stdin.readline

M, N, L = map(int, input().split(' '))

Ls = list(map(int, input().split(' ')))

animals = list(map(int, input().split(' ')) for _ in range(N))

# M = 4 # 사대
# N = 8 # 동물
# L = 4 # 사정거리

# Ls = [6,1,4,9]
Ls.sort()

# animals = [[7,2],[3,3],[4,5],[5,1],[2,2],[1,4],[8,4],[9,4]]

cnt = 0
for a, b in animals:
    left = 0
    right = len(Ls) - 1
    while left <= right:
        mid = (left + right) // 2

        if abs(Ls[mid] - a) + b > L:
            if Ls[mid] < a:
                left = mid + 1
            else:
                right = mid - 1
        
        else:
            cnt = cnt + 1
            break
    # print(f'a :{a}, b :{b}, cnt: {cnt}')

print(cnt)

'알고리즘' 카테고리의 다른 글

백준 2869 달팽이는 올라가고 싶다  (0) 2023.07.17
프로그래머스, 예산  (0) 2023.07.14
[Hash Table] 백준 10816 숫자 카드 2  (0) 2023.06.11
백준 2470 두 용액  (0) 2023.06.01
백준 2110 공유기 설치  (0) 2023.05.31