ν‹°μŠ€ν† λ¦¬ λ·°

728x90
λ°˜μ‘ν˜•

문제

 

20057번: λ§ˆλ²•μ‚¬ 상어와 토넀이도

λ§ˆλ²•μ‚¬ 상어가 토넀이도λ₯Ό λ°°μ› κ³ , μ˜€λŠ˜μ€ 토넀이도λ₯Ό 크기가 N×N인 격자둜 λ‚˜λˆ„μ–΄μ§„ λͺ¨λž˜λ°­μ—μ„œ μ—°μŠ΅ν•˜λ €κ³  ν•œλ‹€. μœ„μΉ˜ (r, c)λŠ” 격자의 rν–‰ c열을 μ˜λ―Έν•˜κ³ , A[r][c]λŠ” (r, c)에 μžˆλŠ” λͺ¨λž˜μ˜ 양을

www.acmicpc.net

 

문제 풀이

 5 x 5 크기의 토넀이도가 λ°©ν–₯을 μ „ν™˜ν•˜λ©°, ν˜„μž¬ μžˆλŠ” λͺ¨λž˜μ— 영ν–₯을 λ―ΈμΉ˜λŠ” λ¬Έμ œμ΄λ‹€. 문제λ₯Ό ν’€κΈ° μœ„ν•΄μ„œλŠ” `상, ν•˜, 쒌, 우`둜 μ „ν™˜λ˜λŠ” 경우의 토넀이도에 λŒ€ν•΄ 사전에 μ΄ˆκΈ°ν™”κ°€ ν•„μš”ν•˜λ‹€.

 

tornado = [
    (None, None, 2, None, None),
    (None, 10, 7, 1, None),
    (5, 'a', None, None, None),
    (None, 10, 7, 1, None),
    (None, None, 2, None, None)
]

temp = [tornado]

for idx in range(3):
    temp.append(list(reversed(list(zip(*temp[-1])))))

 μœ„와 같이, 문제의 주어진 쑰건에 맞게 `tornado` 리슀트λ₯Ό μ„ μ–Έν•œ ν›„, λ°˜μ‹œκ³„ λ°©ν–₯으둜 νšŒμ „μ‹œν‚¨λ‹€. 그리고 λ‹€μŒμ€ μ΄μ „μ˜ 값을 κΈ°μ€€μœΌλ‘œ λ‹€μ‹œ νšŒμ „μ‹œν‚€λŠ” 과정을 3번 λ°˜λ³΅ν•˜κ²Œ 되면 `상, ν•˜, 쒌, 우`둜 μ „ν™˜λ˜λŠ” 토넀이도λ₯Ό ꡬ할 수 μžˆλ‹€.

 

 ν† λ„€μ΄λ„μ˜ μ΄ˆκΈ°ν™” 과정이 끝났닀면, λ‹¨μˆœν•œ Flood fill λ¬Έμ œμ™€λŠ” 달리 λ‚˜μ„ ν˜•μœΌλ‘œ λŒμ•„λ‚˜κ°€λ©° 탐색을 μ§„ν–‰ν•˜μ—¬μ•Ό ν•œλ‹€. λ¬Έμ œμ—μ„œ κ·œμΉ™μ€ `쒌, ν•˜, 우, 상`으둜 움직이며 μ›€μ§μ΄λŠ” κ±°λ¦¬λŠ” `ν•˜ → 우`, `상 → 쒌` 인 κ²½μš°μ— 거리가 1μ”© μ¦κ°€ν•˜κ²Œ λœλ‹€. 즉, μœ„ κ·Έλ¦Όμƒμ—μ„œ 빨간색 ν™”μ‚΄ν‘œμΈ κ²½μš°μ™€, λ…Έλž€μƒ‰ ν™”μ‚΄ν‘œμΈ κ²½μš°μ— μ΄λ™ν•˜λŠ” 거리가 1μ”© μ¦κ°€ν•œλ‹€.

 

 λ‚˜λ¨Έμ§€λŠ” λ¬Έμ œμ—μ„œ μš”κ΅¬ν•˜λŠ” 것과 같이 λ™μž‘ν•˜λ„λ‘ ν•œλ‹€λ©΄ λ¬Έμ œμ—μ„œ μ›ν•˜λŠ” 닡을 찾을 수 μžˆλ‹€.

 

μ½”λ“œ

from sys import stdin
from copy import deepcopy


def visitable(cur_x, cur_y):
    return 0 <= cur_x < N and 0 <= cur_y < N


def init_tornado():
    global tornado

    temp = [tornado]

    # anti-clockwise
    for idx in range(3):
        temp.append(list(reversed(list(zip(*temp[-1])))))

    tornado = deepcopy(temp)


def spread(cur_tornado, loc):
    global answer, A

    cur_x, cur_y = loc
    # tornado λ°°μ—΄μ˜ μœ„μΉ˜λ₯Ό μΌμΉ˜μ‹œν‚€κΈ° μœ„ν•΄ -2μ”© κ°μ†Œ
    tdx, tdy = cur_x - 2, cur_y - 2

    # 'a'에 λ“€μ–΄κ°ˆ 값을 λˆ„μ ν•˜κΈ° μœ„ν•¨
    a = 0
    # 'a'의 μœ„μΉ˜λ₯Ό 기둝
    a_loc = None

    for tx in range(5):
        for ty in range(5):
            nx, ny = tx + tdx, ty + tdy
            # λͺ¨λž˜μ— 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠλŠ” 경우
            if cur_tornado[tx][ty] is None:
                continue
            # 숫자둜, λͺ¨λž˜κ°€ 흩날렀 κ°€λŠ” 경우
            elif cur_tornado[tx][ty] != 'a':
                cur_sand = (A[cur_x][cur_y] * cur_tornado[tx][ty]) // 100
                if visitable(nx, ny):
                    A[nx][ny] += cur_sand
                else:
                    answer += cur_sand
                a += cur_sand
            # a인 경우, 값을 차후에 λ°˜μ˜ν•˜κΈ° μœ„ν•΄ 기둝
            else:
                a_loc = (tx, ty)

    # λˆ„μ λœ 'a' 값을 반영
    nx, ny = a_loc[0] + tdx, a_loc[1] + tdy
    cur_sand = A[cur_x][cur_y] - a

    if visitable(nx, ny):
        A[nx][ny] += cur_sand
    else:
        answer += cur_sand

    A[cur_x][cur_y] = 0


if __name__ == '__main__':
    answer = 0

    tornado = [
        (None, None, 2, None, None),
        (None, 10, 7, 1, None),
        (5, 'a', None, None, None),
        (None, 10, 7, 1, None),
        (None, None, 2, None, None)
    ]

    dirs = ((0, -1), (1, 0), (0, 1), (-1, 0))
    N = int(stdin.readline())
    A = [list(map(int, stdin.readline().split())) for _ in range(N)]

    init_tornado()

    dist = 1
    x = y = N // 2

    while True:
        for cur_dir in range(4):
            dx, dy = dirs[cur_dir]
            
            for _ in range(dist):
                next_x, next_y = x + dx, y + dy

                # 토넀이도 μ†Œλ©Έ 지점
                if (next_x, next_y) == (0, -1):
                    print(answer)
                    exit(0)

                spread(tornado[cur_dir], [next_x, next_y])

                x, y = next_x, next_y

            # 거리가 μΆ”κ°€λ˜λŠ” 것은 2, 4번째인 경우.
            dist += 1 if cur_dir == 1 or cur_dir == 3 else 0

 

728x90
λ°˜μ‘ν˜•
λŒ“κΈ€
κΈ€ 보관함
μ΅œκ·Όμ— 올라온 κΈ€
μ΅œκ·Όμ— 달린 λŒ“κΈ€