728x90
난이도 : 골드3
풀이일 : 07053
https://www.acmicpc.net/problem/2146
2146번: 다리 만들기
여러 섬으로 이루어진 나라가 있다. 이 나라의 대통령은 섬을 잇는 다리를 만들겠다는 공약으로 인기몰이를 해 당선될 수 있었다. 하지만 막상 대통령에 취임하자, 다리를 놓는다는 것이 아깝다
www.acmicpc.net
링크로 이동하기 귀찮은 분들을 위한 문제 캡쳐
풀이 코드
import sys
from collections import deque
# 섬 고유번호 설정 함수
def islandnum(a, b, num):
queue = deque()
queue.append((a, b))
while queue:
i, j = queue.popleft()
for k in range(4):
ni, nj = i + di[k], j + dj[k]
if 0 <= ni < N and 0 <= nj < N and world[ni][nj] == 1:
world[ni][nj] = num
queue.append((ni, nj))
return
# 다리 구축 함수
def bridge(a, b, num):
queue = deque()
queue.append((a, b))
visited = [[0]*N for _ in range(N)]
visited[a][b] = 1
while queue:
i, j = queue.popleft()
for k in range(4):
ni, nj = i + di[k], j + dj[k]
if 0 <= ni < N and 0 <= nj < N and not visited[ni][nj]:
# 바다
if not world[ni][nj]:
visited[ni][nj] = visited[i][j] + 1
queue.append((ni, nj))
# 다른 섬
if world[ni][nj] and world[ni][nj] != num:
return visited[i][j] - 1
return N ** N
N = int(sys.stdin.readline().strip())
world = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]
island = 2
mini = N ** N
di = [-1, 1, 0, 0]
dj = [0, 0, -1, 1]
# 섬 고유번호 설정
for x in range(N):
for y in range(N):
if world[x][y] == 1:
world[x][y] = island
islandnum(x, y, island)
island += 1
# 다리 구축
for x in range(N):
for y in range(N):
if world[x][y]:
mini = min(mini, bridge(x, y, world[x][y]))
print(mini)
코드 구성
- 섬 구분을 위한 고유 숫자 설정 함수 BFS
- 서로 다른 섬 사이의 다리 구축 함수 BFS
- 바다를 만나면 다리 길이를 늘림
- 다른 섬을 만나면 다리 길이 반환
- 주어진 세계에서 1을 만나면 해당 칸과 연결된 지역 숫자 변경을 위한 함수 실행
- 주어진 세계에서 땅을 만나면 다리 구축 함수 실행
느낀점
BFS를 두 번 사용해서 풀었다.
한 번 틀렸던 문제인데 너무 오래전에 시도했던 문제라 잘 기억도 나지 않는다. 틀리면 메모해둬야겠다.
너무 오랜만에 파이썬 문제를 풀어서 기분이 좋다. 그냥 티어 높은 문제를 풀어서인 것 같지만ㅎㅎ
앞으로는 자바 문제랑 같이 파이썬 문제도 꾸준히 풀어야지
'알고리즘 > 🥇 골드' 카테고리의 다른 글
백준 13418 학교 탐방하기 파이썬 풀이, 반례 (1) | 2023.07.08 |
---|---|
백준 1197 최소 스패닝 트리 파이썬 풀이 (0) | 2023.07.07 |
백준 2638 치즈 파이썬 풀이 반례 (0) | 2023.05.15 |
백준 2206 벽 부수고 이동하기 파이썬 풀이 (1) | 2023.05.13 |
백준 1600 말이 되고픈 원숭이 파이썬 풀이 (0) | 2023.05.12 |