N
: 점의 개수
M
: 선분의 개수
locations
: N개의 점 좌표
N개의 점 좌표와 M개의 선분의 시작점-끝점 좌표를 입력받아 N개의 점 좌표 중 각 선분에 있는 좌표의 수를 M번 구하는 문제이다.
⭐️ 좌표 입력 조건
- 좌표는 같은 좌표 ❌ → 서로 다른 좌표
- 모든 좌표의 크기 범위가 매우 큼을 주의해야 한다.
M개의 선분에 접근해서 선분의 범위 내에서 시작점에 가까운 점과 끝점에 가까운 점을 찾는다.
→ 각 점에 이분탐색을 진행한다.
0
, 끝 N - 1
(인덱스로 접근할 것이므로)0
, 끝 N - 1
(인덱스로 접근할 것이므로)그 두 점 사이의 점 개수를 세서 출력하면 된다.
→ 찾은 점들의 인덱스 차를 구한다면 for문을 이용해서 하나씩 세지 않아도 될 것 같다!
점 좌표 정렬 →
2개의 이분탐색을 M번 반복 →
최종 시간복잡도
가 되어 최악의 경우 로 1초 내에 연산이 가능하다.
M개의 선분을 2개의 이분탐색으로 상한, 하한을 찾아 그 사이 점의 좌표 수 구하기
def find_end(locations, target):
start, end = 0, N - 1
while start <= end:
mid = (start + end) // 2
if locations[mid] < target:
start = mid + 1
else:
end = mid - 1
return start
2 2 3 2 0
으로 틀리게 나왔다.<
이 아닌 <=
를 사용해야 했다.import sys
input = sys.stdin.readline
# 시작점과 가까운 점을 찾기
def find_start(locations, target):
start, end = 0, N - 1
while start <= end:
mid = (start + end) // 2
if locations[mid] < target:
start = mid + 1
else:
end = mid - 1
return start
# 끝점과 가까운 점을 찾기
def find_end(locations, target):
start, end = 0, N - 1
while start <= end:
mid = (start + end) // 2
if locations[mid] <= target:
start = mid + 1
else:
end = mid - 1
return start
# N, M 입력
N, M = map(int, input().split())
# N개의 좌표 입력
locations = list(map(int, input().split()))
# M개의 선분의 시작점 끝점 입력
lines = [list(map(int, input().split())) for _ in range(M)]
# 좌표 정렬
locations.sort()
# 각 선분에 대해 계산
for line in lines:
start, end = line
start_idx = find_start(locations, start)
end_idx = find_end(locations, end)
# 결과 출력
print(end_idx - start_idx)