➰ 취업준비/알고리즘 문제풀이

[삼성/코테기출][Python][백준][20057] 마법사 상어와 토네이도 (시뮬레이션/구현)

 사과개발자 2021. 4. 16. 20:55

🍋 문제링크

 

20057번: 마법사 상어와 토네이도

마법사 상어가 토네이도를 배웠고, 오늘은 토네이도를 크기가 N×N인 격자로 나누어진 모래밭에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c열을 의미하고, A[r][c]는 (r, c)에 있는 모래의 양을

www.acmicpc.net

🍎 코드 제출 기록 (메모리 및 시간)

메모리 : 160596 KB

시간 : 344 ms

🥝 메모

  • 골드 4 체감 쉬운 문제
  • 구현보다 이해하는 시간이 더 오래걸리는 문제

🍓 문제풀이

1. 토네이도가 도는 순서

2. 토네이도의 방향에 따른 모래 이동 dr, dc

🍉 Code

dr=[]
dc=[]
sand=[]

def fill_sand():
    for i in range(N): sand.append(list(map(int, input().split())))

def fill_dr_dc(N):
    for i in range(1, N, 2):
        for j in range(i): dr.append(0); dc.append(-1)
        for j in range(i): dr.append(1); dc.append(0)
        for j in range(i+1): dr.append(0); dc.append(1)
        for j in range(i+1): dr.append(-1); dc.append(0)
    for i in range(N): dr.append(0); dc.append(-1)

def move_sand1(next_sand, _r, _c, outer_sand, dr, dc):
    sum_sand = 0
    if ((0 <= (_r + 2*dr) < N) and (0 <= (_c + 2*dc) < N)):  sand[_r + 2*dr][_c +2*dc] += int(next_sand * (0.05))
    else: outer_sand += int(next_sand * (0.05));
    sum_sand += int(next_sand * (0.05))
    if ((0 <= (_r + dr - 1) < N) and (0 <= (_c +dc) < N)):  sand[_r + dr - 1][_c + dc] += int(next_sand * (0.1))
    else: outer_sand += int(next_sand * (0.1));
    sum_sand += int(next_sand * (0.1))
    if ((0 <= (_r + dr + 1) < N) and (0 <= (_c + dc) < N)): sand[_r + dr + 1][_c + dc] += int(next_sand * (0.1))
    else: outer_sand += int(next_sand * (0.1));
    sum_sand += int(next_sand * (0.1))
    if ((0 <= (_r - 1) < N) and (0 <= (_c + 0) < N)):  sand[_r - 1][_c + 0] += int(next_sand * (0.07))
    else: outer_sand += int(next_sand * (0.07));
    sum_sand += int(next_sand * (0.07))
    if ((0 <= (_r + 1) < N) and (0 <= (_c + 0) < N)):  sand[_r + 1][_c + 0] += int(next_sand * (0.07))
    else: outer_sand += int(next_sand * (0.07));
    sum_sand += int(next_sand * (0.07))
    if ((0 <= (_r + 2) < N) and (0 <= (_c + 0) < N)):  sand[_r + 2][_c + 0] += int(next_sand * (0.02))
    else: outer_sand += int(next_sand * (0.02));
    sum_sand += int(next_sand * (0.02))
    if ((0 <= (_r - 2) < N) and (0 <= (_c + 0) < N)):  sand[_r - 2][_c + 0] += int(next_sand * (0.02))
    else: outer_sand += int(next_sand * (0.02));
    sum_sand += int(next_sand * (0.02))
    if ((0 <= (_r -dr + 1) < N) and (0 <= (_c - dc) < N)):  sand[_r -dr + 1][_c - dc] += int(next_sand * (0.01))
    else: outer_sand += int(next_sand * (0.01));
    sum_sand += int(next_sand * (0.01))
    if ((0 <= (_r -dr - 1) < N) and (0 <= (_c - dc) < N)):  sand[_r -dr - 1][_c - dc] += int(next_sand * (0.01))
    else: outer_sand += int(next_sand * (0.01));
    sum_sand += int(next_sand * (0.01))

    if ((0 <= (_r + dr) < N) and (0 <= (_c + dc) < N)):  sand[_r + dr][_c + dc] += (next_sand - sum_sand)
    else: outer_sand += (next_sand - sum_sand)

    return outer_sand

def move_sand2(next_sand, _r, _c, outer_sand, dr, dc):
    sum_sand = 0
    if ((0 <= (_r + 2*dr) < N) and (0 <= (_c + 2*dc) < N)):  sand[_r + 2*dr][_c +2*dc] += int(next_sand * (0.05))
    else: outer_sand += int(next_sand * (0.05));
    sum_sand += int(next_sand * (0.05))
    if ((0 <= (_r + dr) < N) and (0 <= (_c + dc - 1) < N)):  sand[_r + dr][_c + dc - 1] += int(next_sand * (0.1))
    else: outer_sand += int(next_sand * (0.1));
    sum_sand += int(next_sand * (0.1))
    if ((0 <= (_r + dr) < N) and (0 <= (_c + dc + 1) < N )): sand[_r + dr][_c + dc + 1] += int(next_sand * (0.1))
    else: outer_sand += int(next_sand * (0.1));
    sum_sand += int(next_sand * (0.1))
    if ((0 <= (_r + 0) < N) and (0 <= (_c + 1) < N)):  sand[_r + 0][_c + 1] += int(next_sand * (0.07))
    else: outer_sand += int(next_sand * (0.07));
    sum_sand += int(next_sand * (0.07))
    if ((0 <= (_r + 0) < N) and (0 <= (_c - 1) < N)):  sand[_r + 0][_c - 1] += int(next_sand * (0.07))
    else: outer_sand += int(next_sand * (0.07));
    sum_sand += int(next_sand * (0.07))
    if ((0 <= (_r + 0) < N) and (0 <= (_c + 2) < N)):  sand[_r + 0][_c + 2] += int(next_sand * (0.02))
    else: outer_sand += int(next_sand * (0.02));
    sum_sand += int(next_sand * (0.02))
    if ((0 <= (_r + 0) < N) and (0 <= (_c - 2) < N)):  sand[_r + 0][_c - 2] += int(next_sand * (0.02))
    else: outer_sand += int(next_sand * (0.02));
    sum_sand += int(next_sand * (0.02))
    if ((0 <= (_r -dr) < N) and (0 <= (_c - dc + 1) < N)):  sand[_r -dr][_c - dc + 1] += int(next_sand * (0.01))
    else: outer_sand += int(next_sand * (0.01));
    sum_sand += int(next_sand * (0.01))
    if ((0 <= (_r -dr) < N) and (0 <= (_c - dc - 1) < N)):  sand[_r -dr][_c - dc - 1] += int(next_sand * (0.01))
    else: outer_sand += int(next_sand * (0.01));
    sum_sand += int(next_sand * (0.01))

    if ((0 <= (_r + dr) < N) and (0 <= (_c + dc) < N)):  sand[_r + dr][_c + dc] += (next_sand - sum_sand)
    else: outer_sand += (next_sand - sum_sand)

    return outer_sand

if __name__ == '__main__':
    N = int(input())
    outer_sand = 0
    fill_sand()
    fill_dr_dc(N)

    _r = (N//2) #가운데 칸의 인덱스
    _c = (N//2)
    for i in range(len(dr)):
        _r = _r + dr[i]; _c = _c + dc[i]
        next_sand = sand[_r][_c]
        if dr[i] == 0:
            outer_sand = move_sand1(next_sand, _r, _c, outer_sand, dr[i], dc[i])
        else:
            outer_sand = move_sand2(next_sand, _r, _c, outer_sand, dr[i], dc[i])
        sand[_r][_c] = 0

    print(outer_sand)
반응형