-
백준 16236 아기상어Algorithm/BOJ 2021. 3. 10. 18:08728x90
출처: www.acmicpc.net/problem/16236
분류: BFS
접근방식
상어가 먹이를 찾을 수 없을 때가지 최단거리의 먹이를 찾아 bfs를 돌려주면 되는 문제였습니다.
기술적으로 크게 어려운 것은 없었으나... 익숙하지 않다면 구현에서 좀 애를 먹을 수 있을 것 같네요..! (후 힘들었습니다..)
같은 거리의 먹이들이 여러 개라면 요구사항대로 정렬을 해줘야 합니다! row 우선, 그다음 col로 ..!
feeds.sorted(by: { $0.r == $1.r ? $0.c < $1.c : $0.r < $1.r})
큐에서 DoubleStackQueue를 사용했는데 그냥 배열로 해서 removeFirst해도 통과가 가능한 것 같습니다.해결방법
struct DoubleStackQueue<Element> { private var inbox: [Element] = [] private var outbox: [Element] = [] var isEmpty: Bool{ return inbox.isEmpty && outbox.isEmpty } var count: Int{ return inbox.count + outbox.count } var front: Element? { return outbox.last ?? inbox.first } init() { } init(_ array: [Element]) { self.init() self.inbox = array } mutating func enqueue(_ n: Element) { inbox.append(n) } mutating func dequeue() -> Element { if outbox.isEmpty { outbox = inbox.reversed() inbox.removeAll() } return outbox.removeLast() } } extension DoubleStackQueue: ExpressibleByArrayLiteral { init(arrayLiteral elements: Element...) { self.init() inbox = elements } } let n = Int(readLine()!)! var map = [[Int]]() typealias Point = (r: Int, c: Int) var start: Point! for r in 0..<n { map.append(readLine()!.split(separator: " ").map { Int(String($0))! }) if let baby = map[r].enumerated().filter({ $0.element == 9 }).first { start = (r, baby.offset) map[r][baby.offset] = 0 } } func nexts(_ p: Point) -> [Point] { return [ Point(p.r-1, p.c), Point(p.r, p.c-1), Point(p.r, p.c+1), Point(p.r+1, p.c), ] } func isInRange(_ p: Point) -> Bool { return 0..<n ~= p.r && 0..<n ~= p.c } func nearbyFeed(_ start: Point) -> (Int, Point)? { var dist = [[Int]](repeating: [Int](repeating: 0, count: n), count: n) dist[start.r][start.c] = 0 var q = DoubleStackQueue<Point>() q.enqueue(start) var nearst = -1 var feeds = [Point]() while !q.isEmpty { let curr = q.dequeue() for next in nexts(curr) where isInRange(next) && next != start { if dist[next.r][next.c] == 0, map[next.r][next.c] <= shark { q.enqueue(next) dist[next.r][next.c] = dist[curr.r][curr.c] + 1 if map[next.r][next.c] != 0, map[next.r][next.c] < shark { if dist[next.r][next.c] < nearst || nearst == -1 { nearst = dist[next.r][next.c] feeds = [next] } else if nearst == dist[next.r][next.c] { feeds.append(next) } } } } } let nearstPoint = feeds.sorted(by: { $0.r == $1.r ? $0.c < $1.c : $0.r < $1.r}).first return (nearstPoint == nil || nearst == -1) ? nil : (nearst, nearstPoint!) } var shark = 2 var feeds = 0 var moving = 0 while let (dist, next) = nearbyFeed(start) { start = next moving += dist map[next.r][next.c] = 0 feeds += 1 if shark == feeds { feeds = 0 shark += 1 } } print(moving)
배운점
연습!! 노오오오오오오력으로 간다
'Algorithm > BOJ' 카테고리의 다른 글
백준 17142 연구소 3 (0) 2021.03.17 백준 10819 차이를 최대로 (0) 2021.03.16 백준 12100 2408(easy) (0) 2021.03.08 백준 18808 스티커 붙이기 (0) 2021.03.07 백준 2143 두 배열의 합 (0) 2021.03.05