Search
Duplicate
🥇

마법사 상어와 파이어스톰

주차
문제번호
20058
언어
Python
티어
골드
유형
구현
DFS
nj_Blog
O
nj_상태
완료
이해도
풀이
사람
이해도 2
13 more properties

문제링크

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

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

제출 날짜

@4/16/2021

메모리

297264 KB

시간

1400 ms

메모

2020 하반기 삼성전자 SW 역량 테스트

1. 깊은 복사와 얕은 복사

ice 의 배열을 tmp에 그대로 복사하기 위해서
tmp = ice
Python
복사
를 하면 얕은 복사를 하기 때문에 ice 배열의 원소를 변경하면 tmp 배열의 원소도 같이 변하기 때문에 tmp의 역할을 제대로 수행 할 수 없다. 따라서,
import copy tmp = copy.deepcopy(ice)
Python
복사
위와 같은 깊은 복사를 해주어야 한다.

2. 최대 재귀 깊이

Python이 정한 최대 재귀 깊이는 sys.getrecursionlimit()을 이용해 확인할 수 있다. BOJ의 채점 서버에서 이 값이 1,000으로 되어 있기 때문에 Python이 정한 최대 재귀 깊이보다 재귀의 깊이가 더 깊어질 때 런타임에러(RecursionError)가 발생하게 된다.
import sys sys.setrecursionlimit(10**5)
Python
복사
이를 방지하기 위해서는, 위의 코드와 같이 sys.setrecursionlimit()을 사용하여 Python이 정한 최대 재귀 깊이를 변경하면 된다.

문제풀이

1. 2L × 2L 크기의 부분 격자 시계방향으로 90도 회전한다.

def rotate_ice(ice_width, box_width): tmp = copy.deepcopy(ice) for i in range(0, ice_width, box_width): for j in range(0, ice_width, box_width): for r in range(box_width): for c in range(box_width): ice[i+r][j+c] = tmp[i+box_width-1-c][j+r] if __name__ == '__main__': for L in L_list: rotate_ice(ice_width, 2**L)
Python
복사

2. 얼음이 있는 칸 3개, 4개와 인접해있지 않은 칸은 얼음의 양이 1 줄어든다.

def melt_ice(dir, ice_width): tmp = copy.deepcopy(ice) for i in range(ice_width): for j in range(ice_width): cnt = 0 for d in dir: if (0 <= i + d[0] < ice_width) and (0 <= j + d[1] < ice_width): if tmp[i+d[0]][j+d[1]] > 0: cnt += 1 if cnt < 3 and ice[i][j] > 0: ice[i][j] -= 1 if __name__ == '__main__': for L in L_list: melt_ice(dir, ice_width)
Python
복사

3. 1, 2 번 과정을 총 Q번 시전

4. 남아있는 얼음 A[r][c]의 합 계산

sum_all = 0 for i in range(ice_width): sum_all += sum(ice[i]) print(sum_all)
Python
복사

5. 남아있는 얼음 중 가장 큰 덩어리가 차지하는 칸의 개수 계산

def dfs(ice, dir, x, y, ice_width): ret = 1 for d in dir: nx, ny = x + d[0], y + d[1] if (0 <= nx < ice_width) and (0 <= ny < ice_width) and (ice[nx][ny] > 0): ice[nx][ny] = 0 ret += dfs(ice, dir, nx, ny, ice_width) return ret if __name__ == '__main__': ans = 0 for x in range(ice_width): for y in range(ice_width): if ice[x][y] > 0: ice[x][y] = 0 ans = max(ans, dfs(ice, dir, x, y, ice_width)) print(ans)
Python
복사

Code

import copy import sys sys.setrecursionlimit(10**5) ice = [] L_list = [] def rotate_ice(ice_width, box_width): tmp = copy.deepcopy(ice) for i in range(0, ice_width, box_width): for j in range(0, ice_width, box_width): for r in range(box_width): for c in range(box_width): ice[i+r][j+c] = tmp[i+box_width-1-c][j+r] def melt_ice(dir, ice_width): tmp = copy.deepcopy(ice) for i in range(ice_width): for j in range(ice_width): cnt = 0 for d in dir: if (0 <= i + d[0] < ice_width) and (0 <= j + d[1] < ice_width): if tmp[i+d[0]][j+d[1]] > 0: cnt += 1 if cnt < 3 and ice[i][j] > 0: ice[i][j] -= 1 def dfs(ice, dir, x, y, ice_width): ret = 1 for d in dir: nx, ny = x + d[0], y + d[1] if (0 <= nx < ice_width) and (0 <= ny < ice_width) and (ice[nx][ny] > 0): ice[nx][ny] = 0 ret += dfs(ice, dir, nx, ny, ice_width) return ret if __name__ == '__main__': # 입력받기 N, Q = map(int, input().split()) ice_width = 2**N for i in range(ice_width): ice.append(list(map(int, input().split()))) L_list = list(map(int, input().split())) dir = [[-1,0], [1,0],[0, -1], [0, 1]] for L in L_list: # 회전하기 rotate_ice(ice_width, 2**L) # 0 인 것이 0, 1, 2 개면 -1 melt_ice(dir, ice_width) # print(" ") # for i in range(ice_width): # print(ice[i]) # 전체 얼음의 합 sum_all = 0 for i in range(ice_width): sum_all += sum(ice[i]) print(sum_all) # 가장 큰 덩어리의 크기 ans = 0 for x in range(ice_width): for y in range(ice_width): if ice[x][y] > 0: ice[x][y] = 0 ans = max(ans, dfs(ice, dir, x, y, ice_width)) print(ans)
Python
복사