Skip to content

Commit 51068f2

Browse files
committed
[Gold II] Title: 견우와 직녀, Time: 12 ms, Memory: 79660 KB -BaekjoonHub
1 parent bab810d commit 51068f2

2 files changed

Lines changed: 165 additions & 0 deletions

File tree

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# [Gold II] 견우와 직녀 - 16137
2+
3+
[문제 링크](https://www.acmicpc.net/problem/16137)
4+
5+
### 성능 요약
6+
7+
메모리: 79660 KB, 시간: 12 ms
8+
9+
### 분류
10+
11+
구현, 그래프 이론, 그래프 탐색, 너비 우선 탐색
12+
13+
### 제출 일자
14+
15+
2026년 3월 22일 15:24:27
16+
17+
### 문제 설명
18+
19+
<p>견우와 직녀는 여러 섬과 절벽으로 이루어진 지역에서 살고 있다. 이 지역은 격자로 나타낼 수 있으며, 상하좌우로 인접한 칸으로 가는 데 1분이 걸린다.</p>
20+
21+
<p>7월 7일은 견우와 직녀가 오작교를 건너 만날 수 있는 날이다. 그런데 고령화로 인해서 까마귀와 까치가 예전처럼 커다란 오작교를 만들 수 없다. 그래서 요즘은 일부 절벽에만 다리를 만들어 주고 있고, 그마저도 힘들어서 몇 분 주기로 오작교를 짓고 해체하는 작업을 반복해야 한다. 한 번 지은 오작교는 1분 동안 유지할 수 있다.</p>
22+
23+
<p>예를 들어 오작교가 3분과 4분 주기라면, 건널 수 있는 시간은 아래 그림에서 초록색으로 표시한 부분과 같다.</p>
24+
25+
<table class="table table-bordered" style="width: 100%;">
26+
<tbody>
27+
<tr>
28+
<td style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/ec16292c-82ee-4005-9396-68b7a6553bf0/-/preview/" style="width: 400px; height: 58px;"></td>
29+
<td style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/0b4fc5d2-e569-42eb-8aed-7217c1cbe58a/-/preview/" style="width: 400px; height: 58px;"></td>
30+
</tr>
31+
<tr>
32+
<td style="text-align: center;">T = 3</td>
33+
<td style="text-align: center;">T = 4</td>
34+
</tr>
35+
</tbody>
36+
</table>
37+
38+
<p>오작교는 이처럼 매우 불안정하므로, 견우는 안전을 위해 두 번 연속으로 오작교를 건너지는 않기로 했다.</p>
39+
40+
<p>까마귀와 까치는 조금이라도 견우를 더 도와주기 위해, 절벽을 정확히 하나 골라 주기가 M분인 오작교를 하나 더 놓아 주기로 했다. 단, 이미 오작교를 짓기로 예정한 절벽에는 오작교를 하나 더 놓을 수 없고, 아래와 같이 절벽이 가로와 세로로 교차하는 곳에도 오작교를 놓을 수 없다.</p>
41+
42+
<p>아래 그림에서 파란색은 견우가 건널 수 있는 일반적인 땅, 검은색은 절벽, 흰색은 절벽이 교차해서 오작교를 놓을 수 없는 위치를 나타낸다.</p>
43+
44+
<p style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/478968f8-19f0-4605-9644-94b1cd89c378/-/preview/" style="width: 250px; height: 250px;"><img alt="" src="https://upload.acmicpc.net/e3614d8e-4d04-44ea-9dbb-07e4a2f23328/-/preview/" style="width: 250px; height: 250px;"><img alt="" src="https://upload.acmicpc.net/362105a1-75ca-4286-8f63-684daf820c92/-/preview/" style="width: 250px; height: 250px;"></p>
45+
46+
<p>견우가 직녀에게 도착할 수 있는 최소의 시간을 찾아 보자.</p>
47+
48+
### 입력
49+
50+
<p>첫째 줄에 지형의 행과 열의 크기를 나타내는 정수 N (2 ≤ N ≤ 10)과 새로 만들어지는 오작교의 주기를 의미하는 정수 M(2 ≤ M ≤ 20)이 주어진다.</p>
51+
52+
<p>다음 N개의 줄에는 줄마다 배열의 각 행을 나타내는 N개의 정수가 한 개의 빈칸을 사이에 두고 주어진다. 각 칸에 들어가는 값은 0 이상 20 이하이다.</p>
53+
54+
<p>또한, 각 칸에 들어가는 정수의 의미는 다음과 같다.</p>
55+
56+
<ul>
57+
<li>1: 이동할 수 있는 일반적인 땅</li>
58+
<li>0: 건널 수 없는 절벽</li>
59+
<li>2 이상의 수: 적혀있는 수 만큼의 주기를 가지는 오작교</li>
60+
</ul>
61+
62+
<p>견우의 시작점은 지형의 맨 왼쪽 위 (0, 0) 이고, 직녀가 사는 곳은 지형의 맨 오른쪽 아래인 (N-1, N-1)이다. 견우가 시작점에서 출발하는 시간은 0분이다. 견우와 직녀가 사는 곳은 일반적인 땅이다.</p>
63+
64+
<p>견우와 직녀가 무조건 만날 수 있는 경우만 주어진다. 또한, 주어지는 지형 정보에서 오작교를 반드시 하나 이상 놓을 수 있다. 절벽이 가로와 세로로 교차하는 지점에는 오작교가 설치되어 있지 않다.</p>
65+
66+
### 출력
67+
68+
<p>견우가 직녀에게 갈 수 있는 최소의 시간을 출력한다.</p>
69+
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import Foundation
2+
3+
let input = readLine()!.split(separator: " ").map { Int($0)! }
4+
let N = input[0], M = input[1]
5+
6+
var board = (0..<N).map { _ in
7+
readLine()!.split(separator: " ").map { Int($0)! }
8+
}
9+
10+
let dr = [0, 1, 0, -1]
11+
let dc = [1, 0, -1, 0]
12+
13+
func bfs() -> Int {
14+
var visited = Array(
15+
repeating: Array(
16+
repeating: Array(
17+
repeating: Array(repeating: false, count: 20),
18+
count: 2
19+
),
20+
count: N
21+
),
22+
count: N
23+
)
24+
25+
var queue: [(Int, Int, Int, Int)] = [(0, 0, 0, 0)]
26+
var idx = 0
27+
28+
visited[0][0][0][0] = true
29+
30+
while idx < queue.count {
31+
let (r, c, time, prevBridge) = queue[idx]
32+
idx += 1
33+
34+
if r == N-1 && c == N-1 {
35+
return time
36+
}
37+
38+
let nextTime = time + 1
39+
let mod = nextTime % 20
40+
41+
if !visited[r][c][prevBridge][mod] {
42+
visited[r][c][prevBridge][mod] = true
43+
queue.append((r, c, nextTime, prevBridge))
44+
}
45+
46+
for d in 0..<4 {
47+
let nr = r + dr[d]
48+
let nc = c + dc[d]
49+
50+
if nr < 0 || nr >= N || nc < 0 || nc >= N { continue }
51+
52+
let val = board[nr][nc]
53+
54+
if val == 1 {
55+
if !visited[nr][nc][0][mod] {
56+
visited[nr][nc][0][mod] = true
57+
queue.append((nr, nc, nextTime, 0))
58+
}
59+
}
60+
61+
else if val >= 2 {
62+
if prevBridge == 1 { continue }
63+
64+
if nextTime % val == 0 {
65+
if !visited[nr][nc][1][mod] {
66+
visited[nr][nc][1][mod] = true
67+
queue.append((nr, nc, nextTime, 1))
68+
}
69+
}
70+
}
71+
}
72+
}
73+
74+
return Int.max
75+
}
76+
77+
var answer = Int.max
78+
79+
for i in 0..<N {
80+
for j in 0..<N {
81+
if board[i][j] != 0 { continue }
82+
83+
let vertical = (i > 0 && i < N-1 && board[i-1][j] == 0 && board[i+1][j] == 0)
84+
let horizontal = (j > 0 && j < N-1 && board[i][j-1] == 0 && board[i][j+1] == 0)
85+
86+
if vertical && horizontal { continue }
87+
88+
board[i][j] = M
89+
90+
answer = min(answer, bfs())
91+
92+
board[i][j] = 0
93+
}
94+
}
95+
96+
print(answer)

0 commit comments

Comments
 (0)