코테풀이/백준

13334번: 철로

miimu 2025. 10. 18. 16:05

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

아이디어

  • 각 사람들의 집과 사무실에 상관 없이 선분 상 왼쪽에 있는 곳을 튜플의 왼쪽에 둔다. (x, y) -> x <= y
  • 스위핑 방식 : 사람들 case를 정렬한 후, 각 case마다 오른쪽 점을 기준으로 한 철로를 옮기면서 철로 별 case가 얼마나 있는지 계산한다.
  • case 정렬
    • 철로 안에 있는지 판별을 오른쪽 점인 y를 기준으로 판별하므로, y값을 기준으로 오름차순으로 정렬한다.
    • 철로 좌표 = (start, end)
  • 우선순위큐 사용 
    • 철로 안에 case가 있으면, 해당 case를 queue에 push한다.
    • 철로 안에 없는 new case 차례라면 철로를 옮겨야 한다.
    • 철로를 new case의 end값을 기준으로 설치한다고 가정
      • 이 때, 새 철로 start의 왼쪽에 x값이 있는 선분을 모두 꺼낸다.
  • 각 case가 나올 때마다 현재 철로에서의 모든 case 개수를 카운팅 한다.
# https://www.acmicpc.net/problem/13334
# heapq, sweeping
import sys
import heapq

n = int(input())
loc = [0] * n
for idx in range(n) :
    h, o = map(int, sys.stdin.readline().split())
    if h <= o :
        loc[idx] = (h, o)
    else :
        loc[idx] = (o, h)

d = int(input())        
loc = sorted(loc, key=(lambda x : (x[1], x[0])))

ans = 0
cnt = 0

case = [] # 직원의 집-사무실 케이스

track_start, track_end = loc[0][1] - d, loc[0][1]
for l in loc :
    x, y = l
    if abs(y - x) > d :
        continue
    # 완전 포함일 때
    if track_start <= x and y <= track_end :
        heapq.heappush(case, x)
        cnt = len(case)
    # 일부 포함일 때
    elif track_end < y :
        # track 갱신
        track_start, track_end = y - d, y # track_end 갱신해야 함 -> 그에 따라 track_start도 갱신
        c = case[0]# init
        while case and c < track_start : # 갱신하고 track_start에 미달하는 x 가진 이전 것들 제거해야 함
            c = heapq.heappop(case)
            if track_start <= c :
                heapq.heappush(case, c)
        # 현재 것 넣기
        heapq.heappush(case, x)
        cnt = len(case)
    
    if ans < cnt :
        ans = cnt
    # print(f"cnt : {cnt}, track : ({track_start}, {track_end}), now : ({x}, {y})")

print(ans)

 

'코테풀이 > 백준' 카테고리의 다른 글

15824번: 너 봄에는 캡사이신이 맛있단다  (0) 2025.11.02
1629번: 곱셈  (0) 2025.10.27
2170번: 선 긋기  (0) 2025.10.18
11725번: 트리의 부모 찾기  (0) 2025.10.13
14725번: 개미굴  (0) 2025.10.10