정올/KOI기출 문제

정올 아이템 획득

juwanseo 2025. 5. 11. 20:33
import sys
import bisect

n, q = map(int, input().split())
x, y, w = [0] * n, [0] * n, [0] * n

for i in range(n):
    x[i], y[i], w[i] = map(int, input().split())

xv = [[] for _ in range(202020)]
yv = [[] for _ in range(202020)]
xp = [[] for _ in range(202020)]
yp = [[] for _ in range(202020)]
xs = [[] for _ in range(202020)]
ys = [[] for _ in range(202020)]

def init(arr, pos, sum):
    arr.sort()
    for p,s in arr:
        pos.append(p)
        sum.append(s)
    for i in range(1, len(sum)):
        sum[i] += sum[i-1]

for i in range(n):
    xv[x[i]].append((y[i], w[i]))
    yv[y[i]].append((x[i], w[i]))

for i in range(202020):
    init(xv[i], xp[i], xs[i])
    init(yv[i], yp[i], ys[i])

def get(pos, sum, l, r):
    st = bisect.bisect_left(pos, l)
    ed = bisect.bisect_right(pos, r) - 1
    return sum[ed] - (sum[st-1] if st > 0 else 0) if st <= ed else 0

x, y, res = 1, 1, 0
for i in range(q):
    d, v = map(int, input().split())
    if d == 0:
        res += get(yp[y], ys[y], x+1, x+v)
        x += v
    if d == 1:
        res += get(xp[x], xs[x], y+1, y+v)
        y += v
    if d == 2:
        res += get(yp[y], ys[y], x-v, x-1)
        x -= v
    if d == 3:
        res += get(xp[x], xs[x], y-v, y-1)
        y -= v

print(res)

이 코드는 2차원 좌표 평면 위에 있는 가중치가 있는 점들에 대해, (1,1)에서 시작해 주어진 방향과 거리만큼 움직이며 해당 경로 위에 존재하는 점들의 가중치 합을 계산하는 프로그램이다.

먼저 각 점의 x좌표와 y좌표에 따라 데이터를 정리해서 xv, yv 리스트에 저장하고, 이를 정렬한 뒤 누적합 배열(xs, ys)과 위치 배열(xp, yp)로 변환한다. 그런 다음 각 쿼리에서 방향(d)과 거리(v)를 받아 이동하며, 이동 경로 위에 있는 점들의 누적합을 이진 탐색(bisect)을 통해 빠르게 계산한다. 방향은 0~3으로 각각 오른쪽, 위, 왼쪽, 아래를 의미하며, 해당 방향으로 이동하면서 지나간 점들의 가중치를 res에 더한다. 최종적으로 모든 이동 경로 위에서 얻은 가중치의 총합을 출력한다

'정올 > KOI기출 문제' 카테고리의 다른 글

정올 두 배  (0) 2025.05.11
정올 등교  (0) 2025.05.11
정올 대피소  (0) 2025.05.11
정올 크림빵  (0) 2025.05.11
정올 조약돌  (0) 2025.05.11