본문 바로가기
알고리즘/python

2573번 빙산(python3)

by 펀구구 2022. 2. 6.

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

 

2573번: 빙산

첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을

www.acmicpc.net

bfs를 적용하면 된다.

이 문제의 핵심은 빙산을 깎을 때, 그 깎인 높이가 다른 빙산을 깎을 때 영향을 주면 안된다는 것이다.

나는 처음에 코드를 작성했을 때 배열의 깊은복사를 사용해서 작성했기 때문에 깊은 복사를 사용하지 않고 구현하는 방법을 찾아보았다.

from collections import deque
import copy
N, M = map(int, input().split())
data = []
for _ in range(N):
    data.append(list(map(int, input().split())))

not_one = []
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
visited = [[0] * M for _ in range(N)]
for i in range(N):
    for j in range(M):
        if data[i][j] != 0:
            not_one.append([i, j])

def bfs(a, b):
    queue = deque()
    queue.append([a, b])
    visited[a][b] = 1
    while queue:
        x, y = queue.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < N and 0 <= ny < M:
                if data[nx][ny] != 0 and visited[nx][ny] == 0:
                    visited[nx][ny] = 1
                    queue.append([nx, ny])



ans = 0
temp_data = copy.deepcopy(data)
while True:
    for i in not_one:
        for j in range(4):
            nx = i[0] + dx[j]
            ny = i[1] + dy[j]
            if 0 <= nx < N and 0 <= ny < M:
                if temp_data[nx][ny] == 0:
                    if data[i[0]][i[1]] > 0:
                        data[i[0]][i[1]] -= 1
    temp_data = copy.deepcopy(data)
    count = 0
    flag = False
    visited = [[0] * M for _ in range(N)]
    for i in not_one:
        if data[i[0]][i[1]] != 0 and visited[i[0]][i[1]] == 0:
            flag = True
            bfs(i[0], i[1])
            count += 1
    if not flag:
        ans = 0
        break
    ans += 1
    if count > 1:
        break

print(ans)

위 코드는 내가 처음 작성한 코드다.

from collections import deque
N, M = map(int, input().split())
data = []
for _ in range(N):
    data.append(list(map(int, input().split())))

not_one = []
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
visited = [[0] * M for _ in range(N)]
for i in range(N):
    for j in range(M):
        if data[i][j] != 0:
            not_one.append([i, j])

def bfs(a, b):
    queue = deque()
    queue.append([a, b])
    visited[a][b] = 1
    while queue:
        x, y = queue.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < N and 0 <= ny < M:
                if data[nx][ny] != 0 and visited[nx][ny] == 0:
                    visited[nx][ny] = 1
                    queue.append([nx, ny])
                if data[nx][ny] == 0 and data[x][y] != 0:
                    minus[x][y] += 1



ans = -1
temp_data = copy.deepcopy(data)
while True:
    minus = [[0] * M for _ in range(N)]
    visited = [[0] * M for _ in range(N)]
    count = 0
    flag = False

    for i in not_one:
        if data[i[0]][i[1]] != 0 and visited[i[0]][i[1]] == 0:
            bfs(i[0], i[1])
            count += 1
            flag = True
    if not flag:
        ans = 0
        break
    ans += 1
    if count > 1:
        break
    for i in range(N):
        for j in range(M):
            if data[i][j] - minus[i][j] < 0:
                data[i][j] = 0
            else:
                data[i][j] -= minus[i][j]

print(ans)

 

위 코드는 minus 리스트를 도입해서 다른 빙하에 영향을 주지 않으면서 깎는 것을 구현해냈다.

'알고리즘 > python' 카테고리의 다른 글

11559번 Puyo Puyo(python3)  (0) 2022.02.18
14888번 연산자 끼워넣기(python3)  (0) 2022.02.11
16236번 아기상어(python3)  (0) 2022.02.06
2468번 안전 영역(python3)  (0) 2022.02.05
10026번 적록색약(python3)  (0) 2022.02.05