시간복잡도 계산
가장가장 생각없이 풀었을때를 가정하자 (3 ≤ N, M ≤ 8)
➡️ 총 O(N*M)^4 12^4 20736
뭐여 이거 걍 구현아니여?
def print_arr() :
for line in A :
print(line)
print()
def solution(x, y) :
global N, M, is_three_cnt
if (x== N or y == M) : # 탐색 종료 (마지막줄이거나 마지막칸일때)
return
print('====checking %d,%d====' %(x,y))
print_arr()
if (A[x][y] != 0) : # 벽을 세울 수 없는 경우
return
# 벽세우기
A[x][y] = 1
is_three_cnt += 1
print('new wall has done!')
print_arr()
if (is_three_cnt == 3) : # 3개 벽을모두 세운 경우
res_arr.append(calc_safety()) # 안전영역을 계산하여 저장한다
A[x][y] = 0
is_three_cnt -= 1
print('three has done!\n')
if (y == M-1) : # 한 줄을 넘어갈때 다음줄 탐색
solution(x+1, 0)
else :
solution(x, y+1)
# 벽 세운것 다시 uncheck
A[x][y] = 0
is_three_cnt -= 1
#N, M =map(int,input().split())
#A = [list(map(int,list(input()))) for _ in range(N)]
N, M = 3,3
A = [[0,0,0], [0,0,0], [0,0,0]]
is_three_cnt = 0
res_arr = []
solution(0,0)
print(max(res_arr))
구조를 greedy랑 dfs로 나눌 수 있다.
이다.
구현하다보니 그렇게 간단하지 않았다.
너무 복잡해져서, 더 간단하게 하고 & 더 빨라질 수 있는 레퍼런스를 찾아봤다
for i in range(start, N*M) :
r = i // M # 행 = M으로 나눈 몫
c = i % M # M으로 나눈 나머지는 열
(3 ≤ N, M ≤ 8) 이니 일차원 배열로 쳐도 무방하고, 코드도 훨씬 단순해졌다!
safe_count = sum(_.count(0) for _ in sel_wall) # 안전영역수 계산
한줄로 잘 정리하는 습관을 들이자
import sys
import copy
res_arr = []
dx, dy = [-1,1,0,0], [0,0,-1,1] # 상하좌우 이동
N, M =map(int,input().split())
A = [list(map(int,input().split())) for _ in range(N)] # 그래프 생성
A_copy = copy.deepcopy(A) # 그래프 복사
# dfs
def dfs(x, y, sel_wall) :
sel_wall[x][y] = 2 # 바이러스로 변경
# 상하좌우 탐색
for i in range(4) :
nx, ny = x + dx[i], y+dy[i]
if 0 <= nx < N and 0 <= ny < M : #조건1) 그래프 범위 내에 있으면서
if sel_wall[nx][ny] == 0 : # 조건2) 바이러스가 퍼질 수 있을때
dfs(nx, ny, sel_wall)
def calc_safety(A_copy) :
global N, M
sel_wall = copy.deepcopy(A_copy)
# dfs로 바이러스 퍼트리기
for i in range(N) :
for j in range(M) :
if sel_wall[i][j] == 2 : #바이러스 발견시 dfs
dfs(i, j, sel_wall)
return (sum(_.count(0) for _ in sel_wall)) # 안전영역수 계산
def solution(start, is_three_cnt) :
global N, M
if (is_three_cnt == 3) : # 3개 벽을모두 세운 경우
res_arr.append(calc_safety(A_copy)) # 안전영역을 계산하여 저장한다
return
else : # 벽이 3개 선택되지 않은 경우
for i in range(start, N*M) :
r = i // M # 행 = M으로 나눈 몫
c = i % M # M으로 나눈 나머지는 열
if A_copy[r][c] == 0 : # 해당구역이 0인 경우
A_copy[r][c] = 1 # 벽을 세움
solution(i, is_three_cnt+1)
A_copy[r][c] = 0 # 되돌리기
solution(0,0)
print(max(res_arr))
오예