[백준] 20057번 마법사 상어와 토네이도 _ 문제 풀이

 


1. 문제

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

2. 풀이

삼성 SW 역량테스트 문제입니다. 삼성 문제 중 가장 정답률이 높은데, 예제를 통과하고 이상없이 문제를 통과했습니다.

  • 각 진행 방향에 따라 곱해야되는 값을 가진 배열 A를 생성해서 문제를 풀었습니다. 배열 A를 소스코드로 구현할 때 오류가 있어서 시간을 좀 쏟았는데, 구현이 애매할때는 그냥 다 쓰는게 훨씬 빠를 것 같습니다.
  • (아래, 오른쪽, 위, 왼쪽) 순서로 진행. 크기는 오른쪽에서 위로 갈때와 왼쪽에서 아래로 갈 때 1씩 증가하는 형태를 가집니다.
  • 좌표 row, col 를 생성하고 -1, 0 에 도달할 때 까지 계속해서 while 에서 문제를 풀게 구현했습니다.

자세한 사항은 소스코드를 참조해주세요.

~~~python N = int(input()) maps = [list(map(int, input().split())) for _ in range(N)] row, col = [N//2, N//2]

좌 하 우 상

way = 0 dr = [0, 1, 0, -1] dc = [-1, 0, 1, 0] move_dist = 1 A = [[[0,0,2,0,0], [0,10,7,1,0], [5,0,0,0,0], [0,10,7,1,0], [0,0,2,0,0]]] for i in range(3): A.append([[A[i][c][5-r-1] for c in range(5)] for r in range(5)])

def spread(row, col): global maps, outside_sand origin_val = maps[row][col] spread_val = 0 for r_i in range(5): for c_i in range(5): # 중심으로 부터 주변의 좌표 얻기 side_r = row + r_i - 2 side_c = col + c_i - 2 side_val = origin_val * A[way][r_i][c_i] // 100 spread_val += side_val # 만약 좌표를 벗어나면 if side_r < 0 or side_r >= N or side_c < 0 or side_c >= N: outside_sand += side_val else: maps[side_r][side_c] += side_val

resi_r, resi_c = row + dr[way], col + dc[way]
if 0 <= resi_r < N and 0 <= resi_c < N:
    maps[resi_r][resi_c] += origin_val - spread_val
else:
    outside_sand += origin_val - spread_val
maps[row][col] = 0 

(아래, 오른쪽, 위, 왼쪽) 순서로 진행. 크기는 오른쪽에서 위로 갈때와 왼쪽에서 아래로 갈 때 1씩 증가하는 형태를 가짐.

outside_sand = 0 while True: for _ in range(move_dist): col -= 1 if row == 0 and col == -1: break spread(row, col) way = (way + 1) % 4 if row == 0 and col == -1: break

for _ in range(move_dist):
    row += 1
    spread(row, col)
way = (way + 1) % 4
move_dist += 1

for _ in range(move_dist):
    col += 1
    spread(row, col)
way = (way + 1) % 4

for _ in range(move_dist):
    row -= 1
    spread(row, col)
way = (way + 1) % 4
move_dist += 1

print(outside_sand) ~~~c