본문 바로가기
Problem Solving/BOJ

[Python] 20057. 마법사 상어와 토네이도

by 부르르 2021. 4. 24.

www.acmicpc.net/problem/20057

 

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

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

www.acmicpc.net

 


Point

  • 토네이도가 (0,0) 도달 시 종료
  • 한칸 움직일 때마다 모래를 퍼트림

Tip

  • 반시계 방향 회전가능할 때까지 전진
  • 시간 절약을 위해 현 위치의 모래가 0이 아닐때만 (A[y][x] != 0) 모래를 퍼트림

메모리 (제한: 512MB)

132984 KB

시간 (제한: 1초)

476 ms

결과

100%

 

import sys from collections import deque def spread(y,x,one,seven,two,ten,five,alpha): ​​​​global n, sand_out ​​​​tmp = 0 ​​​​for d in one: ​​​​​​​​ny = y + d[0] ​​​​​​​​nx = x + d[1] ​​​​​​​​sand = ground[y][x] // 100 ​​​​​​​​if 0 <= ny < n and 0 <= nx < n: ​​​​​​​​​​​​ground[ny][nx] += sand ​​​​​​​​else: ​​​​​​​​​​​​sand_out += sand ​​​​​​​​tmp += sand ​​​​for d in seven: ​​​​​​​​ny = y + d[0] ​​​​​​​​nx = x + d[1] ​​​​​​​​sand = ground[y][x] * 7 // 100 ​​​​​​​​if 0 <= ny < n and 0 <= nx < n: ​​​​​​​​​​​​ground[ny][nx] += sand ​​​​​​​​else: ​​​​​​​​​​​​sand_out += sand ​​​​​​​​tmp += sand ​​​​for d in two: ​​​​​​​​ny = y + d[0] ​​​​​​​​nx = x + d[1] ​​​​​​​​sand = ground[y][x] * 2 // 100 ​​​​​​​​if 0 <= ny < n and 0 <= nx < n: ​​​​​​​​​​​​ground[ny][nx] += sand ​​​​​​​​else: ​​​​​​​​​​​​sand_out += sand ​​​​​​​​tmp += sand ​​​​for d in ten: ​​​​​​​​ny = y + d[0] ​​​​​​​​nx = x + d[1] ​​​​​​​​sand = ground[y][x] * 10 // 100 ​​​​​​​​if 0 <= ny < n and 0 <= nx < n: ​​​​​​​​​​​​ground[ny][nx] += sand ​​​​​​​​else: ​​​​​​​​​​​​sand_out += sand ​​​​​​​​tmp += sand ​​​​for d in five: ​​​​​​​​ny = y + d[0] ​​​​​​​​nx = x + d[1] ​​​​​​​​sand = ground[y][x] * 5 // 100 ​​​​​​​​if 0 <= ny < n and 0 <= nx < n: ​​​​​​​​​​​​ground[ny][nx] += sand ​​​​​​​​else: ​​​​​​​​​​​​sand_out += sand ​​​​​​​​tmp += sand ​​​​for d in alpha: ​​​​​​​​ny = y + d[0] ​​​​​​​​nx = x + d[1] ​​​​​​​​sand = ground[y][x] - tmp ​​​​​​​​if 0 <= ny < n and 0 <= nx < n: ​​​​​​​​​​​​ground[ny][nx] += sand ​​​​​​​​else: ​​​​​​​​​​​​sand_out += sand ​​​​ground[y][x] = 0 def sandstrom(y,x,i): ​​​​if ground[y][x] != 0: ​​​​​​​​if i == 0: ​​​​​​​​​​​​spread(y, x, [(-1, 1), (1, 1)], [(-1, 0), (1, 0)], [(-2, 0), (2, 0)], [(-1, -1), (1, -1)], [(0, -2)], [(0, -1)]) ​​​​​​​​elif i == 1: ​​​​​​​​​​​​spread(y, x, [(-1,-1),(-1,1)], [(0,-1),(0,1)], [(0,-2),(0,2)], [(1,-1),(1,1)], [(2,0)], [(1, 0)]) ​​​​​​​​elif i == 2: ​​​​​​​​​​​​spread(y, x, [(-1, -1), (1, -1)], [(-1, 0), (1, 0)], [(-2, 0), (2, 0)], [(-1, 1), (1, 1)], [(0, 2)], [(0, 1)]) ​​​​​​​​else: ​​​​​​​​​​​​spread(y, x, [(1, -1), (1, 1)], [(0, -1), (0, 1)], [(0, -2), (0, 2)], [(-1, -1), (-1, 1)], [(-2, 0)], [(-1, 0)]) def go(y,x): ​​​​check = [[False] * n for _ in range(n)] ​​​​i = 0 ​​​​ny, nx = y + dydx[i][0], x + dydx[i][1] ​​​​check[y][x] = True ​​​​check[ny][nx] = True ​​​​queue = deque([[ny,nx,i]]) ​​​​sandstrom(ny,nx,i) ​​​​while queue: ​​​​​​​​y,x,i = queue.popleft() ​​​​​​​​if (y,x) == (0,0): ​​​​​​​​​​​​break ​​​​​​​​ni = (i+1)%4 ​​​​​​​​ny,nx = y+dydx[ni][0],x+dydx[ni][1] ​​​​​​​​if check[ny][nx]: ​​​​​​​​​​​​ni = i ​​​​​​​​​​​​ny,nx = y+dydx[ni][0],x+dydx[ni][1] ​​​​​​​​check[ny][nx] = True ​​​​​​​​queue.append([ny,nx,ni]) ​​​​​​​​sandstrom(ny, nx, ni) input = sys.stdin.readline n = int(input()) ground = [list(map(int, input().split())) for _ in range(n)] dydx = ((0,-1),(1,0),(0,1),(-1,0)) sand_out = 0 go(n//2,n//2) print(sand_out)

 

문제를 푸는데 도움이 된 테스트 케이스

728x90
반응형

댓글