description |
---|
๊ทธ๋ํํ์ ๊ณจ๋ ๋ฌธ์ |
1707 ์ด๋ถ ๊ทธ๋ํ
๊ทธ๋ํ์ ์ ์ ์งํฉ์ ๋๊ฐ๋ก ๋ถํ ํ์ฌ, ๊ฐ ์งํฉ์ ์ํ ์ ์ ๋ผ๋ฆฌ๋ ์๋ก ์ธ์ ํ์ง ์๋๋ก ๋ถํ ํ ์ ์์ ๋, ์ด๋ถ ๊ทธ๋ํ๋ผ๊ณ ๋ถ๋ฅธ๋ค. ๊ทธ๋ํ๊ฐ ์ฃผ์ด์ก์ผ ใน๋, ์ด๋ถ๊ทธ๋ํ์ธ์ง ํ๋ณํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํด์ผํ๋ค.
- ์ ๋ณด๋ฅผ ์ ๋ ฅ๋ฐ๊ณ , ํ ์คํธ์ผ์ด์ค๋งํผ ๋ฐ๋ณตํ๋ค.
- ๊ทธ๋ํ๋ฅผ ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ๋ก ์ ๋ ฅ๋ฐ๋๋ค. (์๋ฐฉํฅ ๊ฐ์ )
- ์ ์ฒด ๋ ธ๋์ ๋ํด bfs๋ฅผ ํ์ํ๋ฉฐ ์ด๋ถ ๊ทธ๋ํ์ธ์ง ํ๋ณํ๋ค.
- ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ค.
- ์ฐ์ ๋๋ ๋ฌธ์ ๋ฅผ ๋ณด๊ณ ์ด๋ถ ๊ทธ๋ํ์ ์ ํํ ์ ์๋ฅผ ์์ง ๋ชปํ๋ค. (๊ทธ๋ํ์ ์ฌ์ดํด์ด ์๋๊ฐ๋ฅผ ํ์ธํ๋ ๋ฌธ์ ๊ฐ ์๋๋ผ๋ ๊ฒ์ด๋ค)
- ์ํค์ ์ด๋ถ ๊ทธ๋ํ์ ์ ์๋ฅผ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋์์๋ค.
- "๋ชจ๋ ๊ผญ์ง์ ์ ๋นจ๊ฐ, ํ๋์ผ๋ก ์์น ํ๋, ๋ชจ๋ ๋ณ์ด ๋นจ๊ฐ๊ณผ ํ๋ ๊ผญ์ง์ ์ ํฌํจํ๋๋ก ์์น ํ ์ ์๋ค."
- ์ฆ, ใ -ใ ๋ผ๋ ๋ ๊ฐ์ ๋ ธ๋๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฐ์ ์ ์ ์ฅ์์ ํ ์ชฝ์ ๋นจ๊ฐ์, ๋ค๋ฅธ ํ ์ชฝ์ ํ๋์์ผ๋ก ์น ํ ์ ์์ด์ผํ๋ค๋ ๊ฒ์ด๋ค.
- ์ฝ๋ ๊ด์ ์ผ๋ก ์๊ฐํด๋ณด์๋ฉด visited[here]๊ณผ visited[next]์ ๊ฐ์ด ๋ฌ๋ผ์ผํจ์ ์ ์ ์๋ค.
- ์ฃผ์ํด์ผํ ์ ์ ํ๋์ ๊ทธ๋ํ๋ก ์ฃผ์ด์ง์ง ์์ ์ ์๋ค๋ ๊ฒ์ด๋ค.
- ์ฆ, ์ ์ฒด ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธํ๋์ง ํ์ธํ๋ ์์ ์ด ํ์ํ๋ค.
- ๋๋ ํ์ฌ tree์ key๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์ํ๊ณ ์๋ค. ๊ทธ๋์ ํ ์คํธ์ผ์ด์ค์์ ๋ฐ๋์ ํธ๋ฆฌ๋ฅผ ๋น ๋์ ๋๋ฆฌ๋ก ํ ๋ฒ ์ด๊ธฐํํด์ฃผ๋ ์์ ์ด ํ์ํ๋ค. (๋๋ v๋ฅผ ๋ฐ๋ก ์ ์ฅํด์ bfs๋ฅผ ์ํํด๋ ๊ด์ฐฎ๋ค)
- visited๋ฅผ -1๋ก ์ด๊ธฐํํ ์ด์
- ๋๋ ์๋ visited[0]์ผ๋ก ๋ฐฉ๋ฌธํ์ง ์์์์ ํ๊ธฐํ๋ค.
- ์ด์ ๊ณผ๋ ๋ค๋ฅด๊ฒ visited ๋ฐฐ์ด์ 3๊ฐ์ง ์ ๋ณด๋ฅผ ์ ์ฅํด์ผํ๋ค. (์์ง ๋ฐฉ๋ฌธ ์ ํจ, ๋นจ๊ฐ์, ํ๋์)
- ๋๋ ์ด๊ฒ์ -1, 0, 1๋ก ํ๊ธฐํด์ ๋ชจ๋๋ฌ 2๋ฅผ ํตํด here๊ณผ next๋ฅผ ์ฝ๊ฒ ํ๊ธฐํ๊ณ ์ ํ ๊ฒ์ด๋ค!
let testCase = Int(readLine()!)!
var tree = [Int: [Int]]()
var visited = [Int]()
for _ in 0 ..< testCase {
var flag = true
getInformation()
for node in tree.keys {
if node == 0 { continue }
if visited[node] == -1 {
guard bfs(node) else {
print("NO")
flag = false
break
}
}
}
if flag { print("YES") }
}
// ๋ฌธ์ ์์ ์ฃผ์ด์ง๋ ์ ๋ณด๋ฅผ ์
๋ ฅ๋ฐ์
func getInformation() {
let input = readLine()!.split { $0 == " " }.map { Int($0)! }
let (v, e) = (input[0], input[1])
tree = [Int: [Int]]() // ์ด๊ฑฐ ์์ผ๋ฉด ๋ฐํ์ ์๋ฌ. (์ด์ ํค ๊ฐ์ด ํธ๋ฆฌ์ ์ ์ฅ๋์ด ์์)
Array(0...v).forEach { tree[$0] = [] } // dictionary ์ด๊ธฐํ
for _ in 0 ..< e {
let input = readLine()!.split { $0 == " " }.map { Int($0)! }
let (u, v) = (input[0], input[1])
tree[u]!.append(v)
tree[v]!.append(u)
}
visited = [Int](repeating: -1, count: v + 1)
}
func bfs(_ n: Int) -> Bool {
var queue = [n]
visited[n] = 0
var index = 0
while queue.count > index {
let here = queue[index]
index += 1
guard let child = tree[here] else { continue }
for next in child {
// visited[here]๊ณผ visited[next]๊ฐ ๊ฐ๋ค๋ฉด ์ด๋ถ๊ทธ๋ํ๊ฐ ์๋
// here๋ ๋ฐฉ๋ฌธ์ฒ๋ฆฌ๊ฐ ๋์ด์์ผ๋ฏ๋ก -1๊ณผ ๊ฐ์ ์ ์์
guard visited[here] != visited[next] else { return false }
// ํ์ฌ ์ํฉ์ here๊ณผ next์ visited ๊ฐ์ด ๋ค๋ฅธ ์ํฉ์.
// ์ฆ, next๋ here๊ณผ ์์์ด ๋ค๋ฅด๊ฑฐ๋, ์์ง ๋ฐฉ๋ฌธํ์ง ์์ ์ํฉ
// ์์ง ๋ฐฉ๋ฌธํ์ง ์์ ๊ฒฝ์ฐ๋ง queue์ ์ฝ์
ํ๋ค.
guard visited[next] == -1 else { continue }
visited[next] = (visited[here] + 1) % 2
queue.append(next)
}
}
// ใ
-ใ
์์ ํ ๋ฒ๋ ๊ฐ์ ์์ ์น ํ ์ ์๋ค๋ฉด true๋ฅผ ๋ฐํํ๋ค.
return true
}
๋ฐฉํฅ ๊ทธ๋ํ๊ฐ ์ฃผ์ด์ก์ ๋, ์์ ์ ์์ ๋ค๋ฅธ ๋ชจ๋ ์ ์ ์ผ๋ก์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํด์ผํ๋ค.
- ์ฃผ์ด์ง ๊ทธ๋ํ๋ฅผ ๋์ ๋๋ฆฌ ํํ๋ก ์ ๋ ฅ๋ฐ๋๋ค.
- Min Heap ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋ง๋ ๋ค. (Swift๋ heap ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํ์ง ์๋๋ค.)
- ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ์ํํ๋ค.
- ํ ์ ์ ์์ ๋ค๋ฅธ ๋ชจ๋ ์ ์ ์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๊ตฌํ๋ ๋ฐฉ๋ฒ์ ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํด์ผํ๋ค.
- ์ด์ ์ต์ ํ์ ์ ์ํ์ฌ ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํด์ผํ๋ค.
์ต์ ํ ์ฝ๋
// ์ต์ ํ ๊ตฌํ
struct Heap <T: Comparable> {
var heap = [T]()
private func getParent(_ index: Int) -> T {
heap[index / 2]
}
private func getLeftChild(_ index: Int) -> T {
heap[index * 2]
}
private func getRightChild(_ index: Int) -> T {
heap[index * 2 + 1]
}
func isEmpty() -> Bool {
heap.count <= 1
}
mutating func push(_ data: T) {
if isEmpty() { heap.append(data) }
var index = heap.count
heap.append(data)
while index > 1 {
let parent = getParent(index)
guard parent > data else { break }
heap[index] = parent
index /= 2
}
heap[index] = data
}
mutating func pop() -> T? {
guard !isEmpty() else { return nil }
let item = heap[1]
let data = heap.removeLast()
let size = heap.count - 1
guard !isEmpty() else { return item }
var (parent, child) = (1, 2)
while child <= size {
if child < size && getLeftChild(parent) > getRightChild(parent) {
child += 1
}
guard data > heap[child] else { break }
heap[parent] = heap[child]
parent = child
child *= 2
}
heap[parent] = data
return item
}
}
struct Node: Comparable {
static func < (lhs: Node, rhs: Node) -> Bool {
lhs.cost < rhs.cost
}
init(_ node: Int, _ cost: Int) {
self.node = node
self.cost = cost
}
let node: Int
let cost: Int
}
let input = readLine()!.split { $0 == " " }.map { Int($0)! }, (v, e) = (input[0], input[1])
let start = Int(readLine()!)!
var graph = [Int: [Node]]()
var result = [Int](repeating: Int.max, count: v+1)
for i in 1...v {
graph[i] = []
}
for _ in 0 ..< e {
let input = readLine()!.split { $0 == " " }.map { Int($0)! }
let (start, end, cost) = (input[0], input[1], input[2])
graph[start]!.append(Node(end, cost))
}
dijkstra(start)
for i in 1...v {
print(result[i] == Int.max ? "INF" : result[i])
}
func dijkstra(_ start: Int) {
var queue = Heap<Node>()
var visited = [Bool](repeating: false, count: v + 1)
result[start] = 0
queue.push((Node(start, 0)))
while let current = queue.pop() {
let (node, cost) = (current.node, current.cost)
guard !visited[node] else { continue }
visited[node] = true
if let edge = graph[node] {
for next in edge {
let (nextNode, nextCost) = (next.node, next.cost)
guard !visited[nextNode] else { continue }
let newCost = cost + nextCost
if newCost < result[nextNode] {
result[nextNode] = newCost
queue.push(Node(nextNode, newCost))
}
}
}
}
}
N๊ฐ์ ๋์๊ฐ ์๋ค. ํ ๋์์์ ์ถ๋ฐํ์ฌ, ๋ค๋ฅธ ๋์์ ๋์ฐฉํ๋ M๊ฐ์ ๋ฒ์ค๊ฐ ์์ ๋, A ๋์์์ B ๋์๋ก ๊ฐ๋ ์ต์ ๋น์ฉ์ ์ถ๋ ฅํด๋ผ.
- ์ต์ ํ์ ๊ตฌํํ๋ค. (์ค์ํํธ๋ ํ ์ค์ ํ ๋ด๋๋ผ)
- ์ฃผ์ด์ง ์ ๋ณด๋ฅผ ์
๋ ฅ๋ฐ๋๋ค.
- ๋์์ ๊ฐ์๋ฅผ ์ ๋ ฅ ๋ฐ๋๋ค. (๋์ ๋๋ฆฌ์ ํค์ ๊ฐ์๊ฐ ๋๋ค.)
- ๋ฒ์ค์ ๊ฐ์๋ฅผ ์ ๋ ฅ ๋ฐ๋๋ค. (๊ฐ์ ์ ๊ฐ์๊ฐ ๋๋ค.)
- city[์์๋ ธ๋] = [ (๋์ฐฉ๋์, ๋น์ฉ)] ์ผ๋ก ๋์ ๋๋ฆฌ๋ฅผ ์ ๋ ฅ๋ฐ๋๋ค. (์ด๋ ๊ฐ์ฒด๋ ๋น์ฉ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ๋์ด์ผ ํ๋ค)
- ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ์ํํ๋ค.
- ๋์ฐฉ ๋์์ ๋ํ ๋น์ฉ์ ์ถ๋ ฅํ๋ค.
- ์ ํ์ ์ธ ๋ค์ต์คํธ๋ผ ๋ฌธ์ ๋ก ํ ์ ์๋ค.
- ํน์ ๋ ธ๋์์ ๋ค๋ฅธ ๋ ธ๋๋ก ๊ฐ๋๋ฐ์ ์ต์ ๋น์ฉ์ ๊ตฌํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ต์ ํ ์ฝ๋
struct Heap<T: Comparable> {
var heap = [T]()
private func isEmpty() -> Bool {
heap.count <= 1
}
private func getParent(_ index: Int) -> T {
heap[index / 2]
}
private func getLeftChild(_ index: Int) -> T {
heap[index * 2]
}
private func getRightChild(_ index: Int) -> T {
heap[index * 2 + 1]
}
mutating func push(_ data: T) {
if isEmpty() { heap.append(data) }
var index = heap.count
heap.append(data)
while index > 1 {
let parent = getParent(index)
guard parent > data else { break }
heap[index] = parent
index /= 2
}
heap[index] = data
}
mutating func pop() -> T? {
guard !isEmpty() else { return nil }
let item = heap[1]
let last = heap.removeLast()
let size = heap.count - 1
guard !isEmpty() else { return item }
var (parent, child) = (1, 2)
while child <= size {
if size > child, getLeftChild(parent) > getRightChild(parent) {
child += 1
}
if last <= heap[child] { break }
heap[parent] = heap[child]
parent = child
child *= 2
}
heap[parent] = last
return item
}
}
// ํ์ ๋ฃ์ ๋์ ๊ตฌ์กฐ์ฒด์ด๋ค. ๊ฐ์ฒด ๊ฐ ํฌ๊ธฐ๋ cost(๋น์ฉ)์ผ๋ก ๊ฒฐ์ ๋๋ค.
struct City: Comparable {
static func < (lhs: City, rhs: City) -> Bool {
lhs.cost < rhs.cost
}
init(_ city: Int, _ cost: Int) {
self.city = city
self.cost = cost
}
let city: Int
let cost: Int
}
let n = Int(readLine()!)! // ๋์์ ๊ฐ์
let m = Int(readLine()!)! // ๋ฒ์ค์ ๊ฐ์
var city = [Int: [City]]()
Array(1...n).forEach { city[$0] = [] } // ์ฝ์
์ ํธ๋ฆฌํจ์ ์ํด ๋์ ์ ๋ณด๋ฅผ ์ด๊ธฐํํ๋ค.
for _ in 0 ..< m {
let input = readLine()!.split { $0 == " " }.map { Int($0)! }
let (start, end, cost) = (input[0], input[1], input[2])
city[start]!.append(City(end, cost))
}
let input = readLine()!.split { $0 == " " }.map { Int($0)! }
let (startCity, endCity) = (input[0], input[1])
var costs = [Int](repeating: Int.max, count: n + 1)
dijkstra()
print(costs[endCity])
// ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ
func dijkstra() {
var visited = [Bool](repeating: false, count: n+1)
var queue = Heap<City>()
costs[startCity] = 0
queue.push(City(startCity, 0))
while let current = queue.pop() {
let (currentCity, currentCost) = (current.city, current.cost)
guard !visited[currentCity] else { continue }
visited[currentCity] = true
if let edges = city[currentCity] {
for city in edges {
let (nextCity, nextCost) = (city.city, city.cost)
guard !visited[nextCity] else { continue }
let newCost = currentCost + nextCost
if costs[nextCity] > newCost {
costs[nextCity] = newCost
queue.push(City(nextCity, newCost))
}
}
}
}
}
N * M ํ๋ ฌ๋ก ํํ๋๋ ๋งต์ด ์๋ค. 0์ ์ด๋ํ ์ ์๋ ๊ธธ์ด๊ณ 1์ ์ด๋ํ ์ ์๋ ๋ฒฝ์ด๋ฉฐ ์ํ์ข์ฐ๋ก ์ด๋ํ ์ ์๋ค. (1, 1)์์ (N, M)๊น์ง ์ต๋จ๊ฑฐ๋ฆฌ๋ก ์ด๋ํด์ผํ๋ค. ์ด๋ ๊ฑฐ๋ฆฌ๋ ์์ํ๋ ์นธ๊ณผ ๋๋๋ ์นธ๋ ํฌํจ๋์ด์ผํ๋ฉฐ, ์ด๋ ์ค ๋ฒฝ์ ํ ๊ฐ ๊น์ง ๋ถ์๊ณ ์ด๋ํ ์ ์๋ค.
- ๋งต์ ์ ๋ ฅ๋ฐ๋๋ค. (์๊ฐ์ด๊ณผ ์ฃผ์)
- 3์ฐจ์์ visited ๋ฐฐ์ด์ ์ ์ธํ๋ค.
- bfs๋ฅผ ์ํํ๋ค.
- ์๊ฐ์ด๊ณผ ๋๋ฌธ์ ์ฝ์ง ์ด์ด์ด์ด์ด์ด์ด์์ฒญ ํ ๋ฌธ์ ์ด๋ค.
- ์ฒซ ๋ฒ์งธ ์ ๊ทผ - (์ ๋ ๊ฑฐ ๋ปํ์ง๋ง, ๋ฌด์ํ๊ฒ ํ์ด๋ณด์)
- ์ง๋๋ฅผ ์ ๋ ฅ๋ฐ์ ๋, walls๋ผ๋ ๋ฒฝ์ ์์น๋ฅผ ๋ชจ๋ ์ ๋ ฅ๋ฐ์ ํ, ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ํ์ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
- N, M์ ๋ฒ์๊ฐ ์ต๋ 1,000์ด๋ฏ๋ก
$$O(N^2)$$ -> 1,000,000,000,000์ ํ์ฉ.. ๋๋๋ค! - ๋๋ฌด ๋น์ฐํ ์๊ฐ์ด๊ณผ
- N ๋ฒ์งธ ์ ๊ทผ - 3์ฐจ์์ visited ๋ฐฐ์ด์ ์ฌ์ฉํ๋ค. (๋ค๋ฅธ ์ฌ๋๋ค์ ์์ด๋์ด๋ฅผ ์ฐธ๊ณ ํ๋ค.. ๋ค์ฏ์๊ฐ ๊ณ ๋ฏผํจ ใ
)
- visited[n][m][2]๋ฅผ ํตํด์ ์ด์ ๊น์ง ๋ฒฝ์ ๋ถ์ ์ ์์?์ ํ์ธํ๋๊ฒ ํต์ฌ ์์ด๋์ด๋ค.
- Swift๋ 3์ฐจ์ ๋ฐฐ์ด ์์ด๋์ด๋ง์ผ๋ก ์ด ๋ฌธ์ ๋ฅผ ํ ์ ์๋ค. ์๊ฐ์ด๊ณผ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ฐ๋ฆฌ๋ ์๋ฃ๊ตฌ์กฐ์ ๋ ์ ๊ฒฝ์ ์จ์ค์ผ๋๋ค.
- ๊ธฐ๋ณธ์ ์ผ๋ก ์ด์ ๊น์ง ์ฌ์ฉํ๋ Queue.removeFirst๋ O(n)์ด ์์๋๋ค.
- ๊ทธ๋์ ์ด removeFirst๋ฅผ ๋ฐ๊ฟ์ค์ผํ๋๋ฐ, ๋๋ ๋ ๊ฐ์ง ์๋๋ฅผ ํ๋ค.
-
(์คํจ) Queue.reverse -> Queue.removeLast() -> Queue.reverse
Swift์ reverse()๊ฐ O(1)์ด๊ธฐ ๋๋ฌธ์ ์ ํ ๋ฌธ์ ๋์ง ์์๊ฑฐ๋ผ ์๊ฐํ๋๋ฐ, ์๊ฐ์ด๊ณผ๊ฐ ๋ฌ๋ค.. ใ
-
(์ฑ๊ณต) Index๋ฅผ ์ด์ฉํ์ฌ Queue๋ฅผ ํ์ํ๋ ๋ฐฉ๋ฒ
Queue.count > index๋ฅผ while๋ฌธ์ ์กฐ๊ฑด์ผ๋ก ๋ฃ๋ ๋ฐฉ๋ฒ์ด๋ค.
์์ผ๋ก๋ ์ด ๋ฐฉ๋ฒ์ ์ ๊ทน ํ ์ฉ ํด์ผ๊ฒ ๋ค. ใ ใ ใ ใ ใ ใ ใ
-
// ์ด๋ ๊ฐ๋ฅ ๋ฐฉํฅ ์ ์
let dy = [-1, 1, 0, 0]
let dx = [0, 0, 1, -1]
let input = readLine()!.split { $0 == " " }.map { Int(String($0))! }, (n, m) = (input[0], input[1])
var map = [[Bool]]()
var visited = [[[Bool]]](repeating: [[Bool]](repeating: [false, false], count: m), count: n)
for _ in 0 ..< n {
let input = readLine()!.map { $0 == "0" ? true : false }
map.append(input)
}
print(bfs())
func bfs() -> Int {
var queue = [(0, 0, 0, 1)] // (y, x, wall, count)
visited[0][0][0] = true
if (n, m) == (1, 1) { return 1 } // ์์์์น๊ฐ ์ข
๋ฃ์์น๋ผ๋ฉด 1์ ๋ฐํ
var index = 0 // ์๊ฐ์ด๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ
while queue.count > index {
let (y, x, wall, count) = queue[index]
index += 1
for i in 0 ..< 4 {
let ny = dy[i] + y
let nx = dx[i] + x
// ๋งต ๋ฒ์ ๋ด์ ์กด์ฌํ๊ณ , ์์ง ๋ฐฉ๋ฌธํ์ง ์์๋ค๋ฉด
guard 0 ..< n ~= ny && 0 ..< m ~= nx && !visited[ny][nx][wall] else { continue }
// ๋ชฉ์ ์ง์ ๋์ฐฉํ๋ค๋ฉด ๊ฒฐ๊ณผ ๋ฆฌํด
if (ny, nx) == (n-1, m-1) { return count + 1 }
// map์ด true๋ผ๋ฉด (๊ธธ) ๋ฐฉ๋ฌธ์ฒ๋ฆฌ ํ queue์ ์ฝ์
ํ๋ค.
if map[ny][nx] {
visited[ny][nx][wall] = true
queue.append((ny, nx, wall, count + 1))
// map์ด false์ด๊ณ , ์์ง๊น์ง ๋ฒฝ์ ๋ถ์ ์ ์๋ค๋ฉด
} else if wall == 0 {
// ๋ฒฝ ๋ถ์ ์์น์ visited ์ฒ๋ฆฌ
visited[ny][nx][1] = true
// ์๋ก๋ถํฐ ์ถ๋ฐํ๋ ๋ค์ ์์น๋ถํฐ๋ wall์ 1์ด ์ ์ฅ๋๋ค.
queue.append((ny, nx, 1, count + 1))
}
}
}
// ๋ชฉ์ ์ง๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ฉด
return -1
}
์๊ฐ์ด๊ณผ ์ฝ๋ ๋ณด๊ธฐ (์์ ํ์)
let dy = [-1, 0, 1, 0]
let dx = [0, 1, 0, -1]
let input = readLine()!.split { $0 == " " }.map { Int($0)! }, (n, m) = (input[0], input[1])
var map = [[Int]]()
var walls = [(Int, Int)]()
var visited = [[Int]](repeating: [Int](repeating: 0, count: m), count: n)
var result = Int.max
for y in 0 ..< n {
let input = readLine()!.map { Int(String($0))! }
for x in 0 ..< m {
if input[x] == 1 {
walls.append((y, x))
}
}
map.append(input)
}
result = bfs(0, 0)
for (y, x) in walls {
map[y][x] = 0
result = min(result, bfs(0, 0))
map[y][x] = 1
}
print(result == Int.max ? -1 : result)
func bfs(_ y: Int, _ x: Int) -> Int {
var queue = [(y, x)]
visited[y][x] = 1
while !queue.isEmpty {
let (y, x) = queue.removeFirst()
for i in 0 ..< 4 {
let ny = dy[i] + y
let nx = dx[i] + x
guard 0 ..< n ~= ny && 0 ..< m ~= nx && map[ny][nx] == 0 else { continue }
let next = visited[y][x] + 1
guard visited[ny][nx] == 0 || next < visited[ny][nx] else { continue }
if (ny, nx) == (n-1, m-1) {
return next
}
visited[ny][nx] = next
queue.append((ny, nx))
}
}
return Int.max
}
์ฐฝ๊ณ ์ ํ ๋งํ ๊ฐ ๋ณด๊ด๋์ด์๋ค. ๋ณด๊ด ํ ํ๋ฃจ๊ฐ ์ง๋๋ฉด, ์ต์ง ์์ ํ ๋งํ ๋ ์ธ์ ํด์๋ ์ต์ํ ๋งํ ์ ์ํฅ์ ๋ฐ์ ํ๋ฃจ๊ฐ ์ง๋๋ฉด ์ต๊ฒ ๋๋ค. (ํ ๋งํ ๊ฐ ํผ์ ์ ์ ๋ก ์ต๋ ๊ฒฝ์ฐ๋ ์๋ค) ํ ๋งํ ๊ฐ ๋ฉฐ์น ์ด ์ง๋ ๋ค ์ต๊ฒ ๋๋์ง, ์ต์ ์ผ ์๋ฅผ ๊ตฌํด๋ผ. (1์ ์ต์ ํ ๋งํ , 0์ ์ต์ง ์์ ํ ๋งํ , -1์ ํ ๋งํ ๊ฐ ์๋ ์นธ์ด๋ค)
- ์ฃผ์ด์ง ํ ๋งํ ์ ๋ณด๋ฅผ ์
๋ ฅ๋ฐ๋๋ค.
- ์ด๋, ํ ๋งํ ๊ฐ ์ ๋ ฅ ๋ ๊ฒฝ์ฐ, tomato๋ผ๋ ๋ฐฐ์ด์ ๋ฃ๋๋ค.
- ์ ๋ ฅ๋ฐ์ ํ ๋งํ ํ๋ฅผ ์ด์ฉํ์ฌ bfs๋ฅผ ์ํํ๋ค.
- ํ ๋งํ ์์์ 0์ด ์๋ ๊ฒฝ์ฐ๋ง ์ต๋๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค.(์ด๋ํ๋ค)
- ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ค.
- ํ ๋งํ ์์๋ฅผ ์กฐํํ๋ฉฐ 0์ด ํ๋๋ผ๋ ์๋ค๋ฉด -1์ ์ถ๋ ฅํ๋ค.
- ํ ๋งํ ์์์ ์ต๋๊ฐ์ ์ถ๋ ฅํ๋ค.
- ์ฒ์์๋ ๋ชจ๋ ์์ ํ ๋งํ ์ ๋ํด ๊ฐ๊ฐ bfs๋ฅผ ์ํํด์ผํ๋ค๊ณ ์๊ฐํ๋ค.
- ํ์ง๋ง ์์ queue์ ๋ชจ๋ ํ ๋งํ ๋ฅผ ๋ฃ๊ณ ์คํํด๋ depth๋ณ๋ก ์คํ๋๊ธฐ ๋๋ฌธ์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
- ์ฆ bfs ํ ๋ฒ๋ง์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์์ ์๋ฏธํ๋ค.
- ์ด๋ queue์ ๊ธฐ์กด bfs์ฒ๋ผ (0,0)์ด ์๋๋ผ ๋ชจ๋ ํ ๋งํ ๋ฐฐ์ด์ด ๋ค์ด๊ฐ๋ค๋ฉด ๊ฐ๋ฅํ๋ค!
- ์๊ฐ์ด๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ
- ์ฐ์ Swift์์ queue๋ ๋งค์ฐ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค. (removeFirst๋ฅผ ์ง์ํ๋๊น)
- ํ์ง๋ง RemoveFirst๋ ์๊ฐ๋ณต์ก๋ O(n)์ด ์์๋๋ค!!
- ์ฌ๋ฌ๊ฐ์ง ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์๋ค.
- ๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ์ฌ pop ๋ ๊ฒ ์ฒ๋ผ ์ฌ์ฉํ๋ค. (๋ด๊ฐ ์ฑํํ ๋ฐฉ๋ฒ)
- reverse() -> removeFirtst() -> reverse()๋ฅผ ์ฌ์ฉํ๋ค. (reverse๋ O(1)์ด๋ค)
- ์ค์ ํ ๊ตฌํํ๊ธฐ ๋ฑ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์๋ค.
let input = readLine()!.split { $0 == " " }.map { Int($0)! }, (m, n) = (input[0], input[1])
var map = [[Int]]()
var tomato = [(Int, Int)]()
// ์ ๋ณด๋ฅผ ์
๋ ฅ๋ฐ๋๋ค. ๋จ, ํ ๋งํ ์ธ ๊ฒฝ์ฐ ๋ฐ๋ก ๋ฐฐ์ด์ ์ ์ฅํ๋ค.
for y in 0 ..< n {
let input = readLine()!.split { $0 == " " }.map { Int($0)! }
for x in 0 ..< m {
if input[x] == 1 {
tomato.append((y, x))
}
}
map.append(input)
}
bfs()
print(getResult())
func bfs() {
let dy = [-1, 0, 1, 0]
let dx = [0, 1, 0, -1]
var index = 0
// ํ ๋งํ ๋ฐฐ์ด์ ์ด์ฉํ์ฌ bfs๋ฅผ ์ํํ๋ค.
while tomato.count > index {
let (y, x) = tomato[index]
index += 1
for i in 0 ..< 4 {
let ny = dy[i] + y
let nx = dx[i] + x
guard 0..<n ~= ny && 0..<m ~= nx && map[ny][nx] == 0 else { continue }
map[ny][nx] = map[y][x] + 1
tomato.append((ny, nx))
}
}
}
func getResult() -> Int {
var result = 0
for t in map {
if t.contains(0) { return -1 }
result = max(result, t.max()!)
}
return result - 1
}
N*N ๊ณต๊ฐ์ ๋ฌผ๊ณ ๊ธฐ M๋ง๋ฆฌ์ ์๊ธฐ ์์ด 1๋ง๋ฆฌ๊ฐ ์๋ค. ์๊ธฐ์์ด๋ ์, ํ, ์ข, ์ฐ๋ก ์์ง์ผ ์ ์๋ค. ์ด๋, ์๊ธฐ๋ณด๋ค ๋ชธ์ง์ด ํฐ ๋ฌผ๊ณ ๊ธฐ๋ ์ง๋๊ฐ ์ ์๊ณ , ๋ชธ์ง์ด ๊ฐ์ ๋ฌผ๊ณ ๊ธฐ๋ ์ง๋๊ฐ ์ ์๋ค. ๋ฌผ๊ณ ๊ธฐ๊ฐ ์๊ธฐ๋ณด๋ค ๋ชธ์ง์ด ์๋ค๋ฉด, ๋จน์ ์ ์๋๋ฐ ์๊ธฐ ํฌ๊ธฐ ๋งํผ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์ผ๋ฉด 1๋งํผ ์๊ธฐ ์์ด์ ๋ชธ์ง์ด ์ปค์ง๋ค. ์ด๋, ์์ด๊ฐ ๋ช ์ด ๋์ ์๋ง์๊ฒ ๋์์ ์์ฒญํ์ง ์๊ณ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ์ก์๋จน์ ์ ์๋์ง ๊ณ์ฐํด๋ผ.
- ์๊ธฐ์์ด๋ ๋ ์ด์ ๋จน์ ์ ์๋ ๋ฌผ๊ณ ๊ธฐ๊ฐ ๊ณต๊ฐ์ ์๋ค๋ฉด, ์๋ง์์ด์๊ฒ ๋์์ ์์ฒญํ๋ค.
- ๋จน์ ์ ์๋ ๋ฌผ๊ณ ๊ธฐ๊ฐ 1๋ง๋ฆฌ๋ผ๋ฉด, ๊ทธ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์ผ๋ฌ ๊ฐ๋ค.
- ๋จน์ ์ ์๋ ๋ฌผ๊ณ ๊ธฐ๊ฐ 1๋ง๋ฆฌ๋ณด๋ค ๋ง๋ค๋ฉด, ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์ผ๋ฌ ๊ฐ๋ค.
- ๊ฑฐ๋ฆฌ๋ ์๊ธฐ ์์ด๊ฐ ์ง๋๊ฐ์ผํ๋ ์นธ์ ์ต์ ๊ฐ์์ด๋ค.
- ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ๊น์ด ๋ฌผ๊ณ ๊ธฐ๊ฐ ๋ง๋ค๋ฉด, ๊ฐ์ฅ ์์ ์๋ ๋ฌผ๊ณ ๊ธฐ, ๊ทธ๋ฌํ ๋ฌผ๊ณ ๊ธฐ๊ฐ ๋ง๋ค๋ฉด ๊ฐ์ฅ ์ผ์ชฝ์ ์๋ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน๋๋ค.
- n์ ์ ๋ ฅ๋ฐ๋๋ค.
- ์ง๋ ์ ๋ณด๋ฅผ ์
๋ ฅ๋ฐ๋๋ค.
- ์ ๋ ฅ ๊ฐ์ 9๊ฐ ์๋ค๋ฉด ์์ด์ ์์น๋ฅผ ์ ์ฅํ๊ณ , ํด๋น map์ 0์ผ๋ก ์ด๊ธฐํํ๋ค.
- ์ ๋ ฅ ๊ฐ์ด ๋ฌผ๊ณ ๊ธฐ๋ผ๋ฉด, ๋ฌผ๊ณ ๊ธฐ ์งํฉ์ ์ ๋ณด๋ฅผ ์ถ๊ฐํ๋ค.
- bfs๊ฐ 0์ ๋ฆฌํดํ ๋๊น์ง bfs๋ฅผ ์ํํ๋ค.
- ๋ฌผ๊ณ ๊ธฐ ์งํฉ์ด ๋น์ด์๋ค๋ฉด 0์ ๋ฆฌํดํ๋ค. (์ข ๋ฃ์กฐ๊ฑด 1)
- flood fill ์๊ณ ๋ฆฌ์ฆ์ ์ํํ์ฌ depth ๋ณ๋ก ๋๋น ์ฐ์ ํ์์ ์ํํ๋ค.
- ๋ค์ ์์น๊ฐ ๋ฌผ๊ณ ๊ธฐ๋ผ๋ฉด ์์ ๋ฌผ๊ณ ๊ธฐ ๋ฐฐ์ด์ ์ ์ฅํ๊ณ , ์๋๋ผ๋ฉด ๊ณ์ ํ์์ ์ํํ๋ค.
- ๊ฐ์ depth์ ํ์์ด ๋๋๋ฉด ์์ ๋ฌผ๊ณ ๊ธฐ ๋ฐฐ์ด์ ๋ฌผ๊ณ ๊ธฐ๊ฐ ์๋์ง ํ์ธํ๋ค. (์๋ค๋ฉด ๊ณ์ bfs ์ํ)
- ๋ง์ฝ ์์ ๋ฌผ๊ณ ๊ธฐ ๋ฐฐ์ด์ ๋ฌผ๊ณ ๊ธฐ๊ฐ ์๋ค๋ฉด ์กฐ๊ฑด์ ๋ง๋ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์ผ๋ฌ ๊ฐ์ผํ๋ค.
- ์์ ๋ฌผ๊ณ ๊ธฐ ๋ฐฐ์ด์ ์ ๋ ฌํ๋ค. (์ข์๋จ ๋ฌผ๊ณ ๊ธฐ ์ฐพ๊ธฐ)
- ์ ์ญ์ ์๋ ๋ฌผ๊ณ ๊ธฐ ์งํฉ์์ ๋จน์ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ์ ์ธํ๋ค.
- ์ด์ ๋ฌผ๊ณ ๊ธฐ๊ฐ ์์ผ๋ฏ๋ก ํด๋น ์์น๋ฅผ 0์ผ๋ก ์ด๊ธฐํํ๋ค.
- ๋จน์ ๋ฌผ๊ณ ๊ธฐ๋ฅผ +1 ํด์ค๋ค. (์์ด ์ปค์ง๋ ์กฐ๊ฑด)
- map์ ๋ชจ๋ ์กฐํํ๋ค๋ฉด 0์ ๋ฆฌํดํ๋ค. (์ข ๋ฃ์กฐ๊ฑด 2)
- ๊ณ ๋ฏผํด์ผํ๋ ๋ถ๋ถ
- dy, dx์ ๋ฐฉํฅ๋ง์ผ๋ก ์กฐ๊ฑด์ ์ฑ๋ฆฝํ ์ ์๋ค! -> flood fill ์ฌ์ฉ (๋งค์ฐ ์ค์)
- ๋ฌด์กฐ๊ฑด ๊ฐ์ depth์์ ๋จน์ ์ ์๋ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ํ์ธํ ํ ์ ๋ ฌ์ ์ํํด์ค์ผํ๋ค. (๋ฐฑ์ค์ง๋ฌธ)
- ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์ ์ ์๋ ์ํฉ
- ๋จ์ ๋ฌผ๊ณ ๊ธฐ๋ค์ด ์ ๋ถ ๋ค ํฌ๊ธฐ๊ฐ ์์ด๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ ๊ฒฝ์ฐ
- ๋๋ณด๋ค ์์ ๋ฌผ๊ณ ๊ธฐ๊ฐ ์์ง๋ง, ํฐ ๋ฌผ๊ณ ๊ธฐ๋ค์ด ๋ง๊ณ ์์ด์ ๋จน์ง ๋ชปํ๋ ๊ฒฝ์ฐ
- ์ด ๊ฒฝ์ฐ๊ฐ ๊ต์ฅํ ์ค์ํ๋ค.
- return์ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์ ์ํฉ์์๋ง ํด์ค์ผ๋๋ค. (์ด๋ํ ํ์ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์ง ๋ชปํ ์ํฉ์์ depth๋ฅผ ๋ฆฌํด์ํค๋ฉด ํ๋ฆฐ ๋ต์ด ๋์จ๋ค)
- dy, dx์ ๋ฐฉํฅ๋ง์ผ๋ก ์กฐ๊ฑด์ ์ฑ๋ฆฝํ ์ ์๋ค! -> flood fill ์ฌ์ฉ (๋งค์ฐ ์ค์)
- ์์ด ํฌ๊ธฐ ์ ์ ๋ฐฉ๋ฒ
- Swift์ didSet์ ์ฌ์ฉํ๋ฉด ๊น๋ํ๊ฒ ์ธ ์ ์๋ค!
// ๋ฌผ๊ณ ๊ธฐ ์๋ฃํ
struct Fish: Hashable {
let y: Int
let x: Int
var size: Int
}
let n = Int(readLine()!)!
var map = [[Int]]()
var sharkX = 0, sharkY = 0
var fishes = Set([Fish]())
var sharkSize = 2
var ateFish = 0 { // ์์ด ํฌ๊ธฐ ์ ์
didSet {
if ateFish == sharkSize {
sharkSize += 1
ateFish = 0
}
}
}
// ์ฃผ์ด์ง ์ ๋ณด๋ฅผ ์
๋ ฅ๋ฐ๋๋ค.
// ์์ด์ ๊ฒฝ์ฐ, ์์น๋ง ์ ์ฅํ๊ณ , map์๋ 0์ ์ ์ฅํด์ค๋ค.
// ๋ฌผ๊ณ ๊ธฐ์ ๊ฒฝ์ฐ ์งํฉ์ ๋ฃ์ด์ฃผ์.
for y in 0 ..< n {
var input = readLine()!.split { $0 == " " }.map { Int($0)! }
for x in 0 ..< n {
let size = input[x]
switch size {
case 0: break
case 9:
(sharkY, sharkX) = (y, x)
input[x] = 0
default: fishes.insert(Fish(y: y, x: x, size: size))
}
}
map.append(input)
}
var result = 0
while true {
let count = bfs(sharkY, sharkX)
result += count
if count == 0 {
print(result)
break
}
}
func bfs(_ y: Int, _ x: Int) -> Int {
let dy = [-1, 0, 1, 0]
let dx = [0, 1, 0, -1]
var visited = [[Bool]](repeating: [Bool](repeating: false, count: n), count: n)
visited[y][x] = true
var queue = [(y, x)]
var count = 0 // ์ด๋ ๊ฑฐ๋ฆฌ
var fish = [Fish]() // ํ์ฌ depth์์ ๋จน์ ์ ์๋ ๋ฌผ๊ณ ๊ธฐ ์งํฉ
if fishes.isEmpty { return 0 } // ๋จน์ ์ ์๋ ๋ฌผ๊ณ ๊ธฐ๊ฐ ์๋ค๋ฉด 0์ ๋ฆฌํด (์ข
๋ฃ์กฐ๊ฑด1)
while !queue.isEmpty {
count += 1
let depth = queue.count // flood fill
for _ in 0 ..< depth {
let (y, x) = queue.removeFirst()
for i in 0 ..< 4 {
let ny = dy[i] + y
let nx = dx[i] + x
guard 0 ..< n ~= ny && 0 ..< n ~= nx else { continue }
guard !visited[ny][nx] && map[ny][nx] <= sharkSize else { continue }
visited[ny][nx] = true
let next = map[ny][nx]
if [0, sharkSize].contains(next) { // ์ด๋ํ๋ ๊ฒฝ์ฐ
queue.append((ny, nx))
} else { // ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์ ์ ์๋ ๊ฒฝ์ฐ
fish.append(Fish(y: ny, x: nx, size: next))
}
}
}
// ์ด๋ฒ depth์์ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์ ์ ์๋ค๋ฉด
if !fish.isEmpty {
// ์กฐ๊ฑด์ ๋ง๋ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ์ฐพ๋๋ค.
fish = fish.sorted { $0.x < $1.x }.sorted { $0.y < $1.y }
let shark = fish[0]
// ๋ฌผ๊ณ ๊ธฐ ๋ฐฐ์ด์์ ํด๋น ๋ฌผ๊ณ ๊ธฐ๋ฅผ ์ง์ด๋ค.
fishes.remove(shark)
// ์์ด์ ์์น๋ฅผ ์
๋ฐ์ดํธํ๋ค.
(sharkY, sharkX) = (shark.y, shark.x)
// ์ง๋์ 0์ผ๋ก ์ ์ฅํ๋ค.
map[sharkY][sharkX] = 0
// ๋ฌผ๊ณ ๊ธฐ ์๋ฅผ ์ถ๊ฐํ๋ค.
ateFish += 1
// ์ด์ ๊น์ง ์ด๋ํ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฆฌํดํ๋ค.
return count
}
}
// ๋ชจ๋ ์ง๋๋ฅผ ํ์ํ์์๋ ๋ฌผ๊ณ ๊ธฐ๋ฅผ ๋จน์ง ๋ชปํ๋ค(์ข
๋ฃ์กฐ๊ฑด2)
return 0
}
์๋ชป๋ ์ ๊ทผ 1 - ํฌ๊ธฐ๊ฐ ํฐ ๋ฌผ๊ณ ๊ธฐ๋ ์ง๋๊ฐ ์ ์๋ค๊ณ ์๊ฐํ๋ค (๋ฌธ์ ๋ฅผ ์ ์ฝ์)
๋ฌธ์ ๋ฅผ ์ ์ฝ์ด์ผํ๋ ์ด์ ๋ค.
์์ด๋ณด๋ค ๋ชธ์ง์ด ํฐ ๊ฒฝ์ฐ๋ ์์ง์ผ ์ ์๋ค๊ณ ์๊ฐํด์ ๋จ์ distance๋ฅผ ๊ตฌํด์ ๋ฌธ์ ๋ฅผ ํ์์๋ค...
// ๋ฌผ๊ณ ๊ธฐ ๊ตฌ์กฐ์ฒด
struct Fish: Hashable {
var y: Int
var x: Int
var size: Int
init(_ y: Int, _ x: Int, _ size: Int) {
self.y = y
self.x = x
self.size = size
}
}
let dy = [-1, 0, 1, 0]
let dx = [0, 1, 0, -1]
let n = Int(readLine()!)!
var fishes = Set([Fish]())
var shark = Fish(0, 0, 0)
var (count, result) = (0, 0)
// ๋ฌผ๊ณ ๊ธฐ ์ ๋ณด ์
๋ ฅ๋ฐ๊ธฐ
for y in 0 ..< n {
let input = readLine()!.split { $0 == " " }.map { Int(String($0))! }
for x in 0 ..< n {
if input[x] == 9 {
shark = Fish(y, x, 2)
} else if input[x] != 0 {
fishes.insert(Fish(y, x, input[x]))
}
}
}
while true {
if count == shark.size {
count = 0
shark.size += 1
}
// ์กฐ๊ฑด์ ๋ฐ๋ผ ์ ๋ ฌ
var foodFish = Array(fishes).filter { $0.size < shark.size }
.sorted { $0.x < $1.x }
.sorted { $0.y < $1.y }
.sorted {
calculateDistance($0, shark) < calculateDistance($1, shark)
}
guard !foodFish.isEmpty else { break }
let nextFish = foodFish.removeFirst()
fishes.remove(nextFish)
count += 1
result += calculateDistance(shark, nextFish)
(shark.y, shark.x) = (nextFish.y, nextFish.x)
}
print(result)
// ๋ ๋ฌผ๊ณ ๊ธฐ ์ฌ์ด์ ๊ฑฐ๋ฆฌ ๊ณ์ฐ
func calculateDistance(_ shark: Fish, _ fish: Fish) -> Int {
abs(shark.x - fish.x) + abs(shark.y + fish.y)
}
์๋ชป๋ ์ ๊ทผ2 - ๋จ์ bfs๋ก ํ ์ ์๋ ์ด์
์ด๊ฑฐ ๋๋ ค๋ณด๋ฉด ์๋ง ์์ 4๋ฒ์์ 56์ด ๋์ฌ ๊ฒ์ด๋ค.. (์์ฒญ๋ ์ฝ์ง)
// ์์ข์ฐํ๋ก ํ์
let dy = [-1, 0, 0, 1]
let dx = [0, -1, 1, 0]
let n = Int(readLine()!)!
let initialVisited = [[Int]](repeating: [Int](repeating: 0, count: n), count: n)
var visited = initialVisited
var map = [[Int]]()
var shark = (0, 0)
var sharkSize = 2
var result = 0
var ateFish = 0 {
didSet {
if ateFish == sharkSize {
ateFish = 0
sharkSize += 1
}
}
}
for y in 0 ..< n {
let input = readLine()!.split { $0 == " " }.map { Int($0)! }
for x in 0 ..< n {
if input[x] == 9 {
shark = (y, x)
}
}
map.append(input)
}
map[shark.0][shark.1] = 0
bfs()
print(result)
func bfs() {
var queue = [shark]
visited[shark.0][shark.1] = 1
while !queue.isEmpty {
let (y, x) = queue.removeFirst()
for i in 0 ..< 4 {
let ny = y + dy[i]
let nx = x + dx[i]
guard 0 ..< n ~= ny && 0 ..< n ~= nx else { continue }
guard visited[ny][nx] == 0 && map[ny][nx] <= sharkSize else { continue }
visited[ny][nx] = visited[y][x] + 1
queue.append((ny, nx))
if map[ny][nx] != 0 && map[ny][nx] < sharkSize {
ateFish += 1
result += visited[y][x]
queue = [(ny, nx)]
visited = initialVisited
visited[ny][nx] = 1
map[ny][nx] = 0
print(ny, nx, result, sharkSize)
break
}
}
}
}