9019번: DSLR
문제 풀이 아이디어
# 사용해야 하는 알고리즘 = bfs
: bfs를 사용하는 문제의 패턴 = 몇가지 선택지 + 최단시간
: 이 문제도 마찬가지로 D, S, L, R의 4가지 명령어 버튼을 조작해서 최단시간에 탈출해야합니다.
# 문제 풀이 아이디어
: 전형적인 bfs 문제이지만
: 명령어 부분에서 자릿수를 조작하는 것이 조금 까다롭습니다.
:⭐️ 스위프트에서는 문자열로 바꾸어서 조작하지 말고 10의 배수로 나누기를 활용합시다! (속도차이)
: 🚫 더불어서 스위프트는 문자열 조작의 cost가 큽니다. 문자열을 직접 저장하려고 하면 시간초과가 납니다.
코드
struct Queue {
var queue = [Number]()
var index = 0
var isEmpty: Bool {
queue.count - index == 0
}
mutating func push(_ n: Number) {
queue.append(n)
}
mutating func pop() -> Number {
defer {
index += 1
}
return queue[index]
}
}
struct Number {
var value: Int
var record: Int = 0
}
func addRecord(_ record: Int, _ f: String) -> Int {
switch f {
case "D": return record * 10 + 1
case "S": return record * 10 + 2
case "L": return record * 10 + 3
case "R": return record * 10 + 4
default: return 0
}
}
func printRecord(_ record: Int) {
var result = ""
var n = record
let strings = ["", "D", "S", "L", "R"]
while n > 0 {
result = strings[n % 10] + result
n /= 10
}
print(result)
}
let functions = [D, S, L, R]
func D(_ n: Number) -> Number {
let value = (n.value * 2) % 10000
let record = addRecord(n.record, "D")
return Number(value: value, record: record)
}
func S(_ n: Number) -> Number {
let value = n.value - 1 >= 0 ? n.value - 1 : 9999
let record = addRecord(n.record, "S")
return Number(value: value, record: record)
}
func L(_ n: Number) -> Number {
let value = (n.value % 1000) * 10 + (n.value / 1000)
let record = addRecord(n.record, "L")
return Number(value: value, record: record)
}
func R(_ n: Number) -> Number {
let value = (n.value / 10) + (n.value % 10) * 1000
let record = addRecord(n.record, "R")
return Number(value: value, record: record)
}
func bfs(A: Int, B: Int) {
var queue = Queue()
var check = Array(repeating: false, count: 10000)
queue.push(Number(value: A))
check[A] = true
while !queue.isEmpty {
let now = queue.pop()
if now.value == B { printRecord(now.record); return }
for i in 0..<4 {
let next = functions[i](now)
if !check[next.value] {
queue.push(next)
check[next.value] = true
}
}
}
}
let T = Int(readLine()!)!
for _ in 0..<T {
let input = readLine()!.split(separator: " ").map { Int(String($0))! }
let (A, B) = (input[0], input[1])
bfs(A: A, B: B)
}
참고한 블로그 🙏
백준 9019번 DSLR - 스위프트(Swift) 시간초과 해결