# 첫 풀이
- 적당한 케이스만 고려해서 완전탐색 방식으로 구현
- 3%에서 오답
import Foundation
let nk = readLine()!.split(separator: " ").map { Int($0)! }; let n = nk[0]; let k = nk[1]
// 같은 시간대에는 세가지 경우만
var visited: [Bool] = .init(repeating: false, count: 100000)
var time = Int.max
var ret = 0
// 동생 찾았을때 Time값이 infinite가 아니면 이미 찾은 상태였으므로 값 비교 후 재귀 완전종료
// ret + 1 여부는 time값 최소 여부에 따라 결정
func go(_ here: Int, _ depth: Int) {
if here > 100000 {
return
}
// 동생 위치 찾았을때
if here == k {
// 동생 위치를 처음 찾았을때
if time == Int.max {
time = depth
ret = 1
} else {
if time > depth {
// 동생 위치를 다른 방법으로 이미 찾은 상태인데 지금의 방법이 더 빠른 방법일때
time = depth
ret += 1
} else {
// 동생 위치를 다른 방법으로 찾았는데 지금 방법이 더 느린 경우 그냥 리턴
return
}
}
}
// 못찾았을때
// 1. 동생 위치보다 오른쪽인 경우
// X-1만 해야해서, 왼쪽으로 depth + 간격만큼 이동했을때 이미 찾은 최소 시간을 벗어나면 안됨
// 다른 곳에서 동생 이미 찾았을때
if here > k {
if time != Int.max && here - k + depth <= time {
// print("RIGHT: \(time), 간격: \(here - k) new time: \(here - k + depth)")
time = here - k + depth
// ret += here - k + depth
ret += 1
return
} else if here - k + depth > time{
return
}
// 동생 아직 못찾은 상태이면서 1번 상태일때
if time == Int.max {
// print("depth: \(depth), here: \(here) k: \(k)")
time = depth + here - k - 1
// ret = depth + here - k
ret += 1
return
}
}
// 2. 동생 위치보다 왼쪽인 경우
// X+1 & 2*X 위치 둘다 검증해봐야됨
if here < k && time > depth && !visited[depth] {
visited[depth] = true
go(here * 2, depth + 1)
go(here - 1, depth + 1)
go(here + 1, depth + 1)
}
}
go(n, 0)
print(time)
print(ret)
# 풀이
- BFS 풀이
- 자잘한 반례가 너무 많았음 (최소최대 신경쓰기, n == k일때 신경쓰기)
import Foundation
struct Queue<T> {
var head = 0
var array: [T?] = []
var count: Int {
return array.count - head
}
var isEmpty: Bool {
return count == 0
}
mutating func enqueue(_ element: T){
array.append(element)
}
mutating func dequeue() -> T? {
guard head < array.count,
let element = array[head] else { return nil }
array[head] = nil
head += 1
let percentage = Double(head) / Double(array.count)
if percentage > 0.25 && array.count > 50 {
array.removeFirst(head)
head = 0
}
return element
}
var front: T? {
if isEmpty {
return nil
} else {
return array[head]
}
}
}
let nk = readLine()!.split(separator: " ").map { Int($0)! }; let n = nk[0]; let k = nk[1]
var q = Queue<Int>()
q.enqueue(n)
var ret: [Int] = .init(repeating: 0, count: 100004)
var visited: [Int] = .init(repeating: 0, count: 100004)
visited[n] = 1
ret[n] = 1
while(!q.isEmpty) {
guard let now = q.front else { break }
_ = q.dequeue()
for next in [now - 1, now + 1, now * 2] {
if next < 0 || next > 100000 {
continue
}
if visited[next] == 0 {
visited[next] = visited[now] + 1
ret[next] += ret[now]
q.enqueue(next)
} else {
if visited[next] == visited[now] + 1 {
ret[next] += ret[now]
}
}
}
}
if n == k {
print(0)
print(1)
} else {
print(visited[k] - 1)
print(ret[k])
}
# 재풀이
import Foundation
struct Queue<T> {
var head = 0
var array: [T?] = []
var count: Int {
return array.count - head
}
var isEmpty: Bool {
return count == 0
}
mutating func enqueue(_ element: T) {
array.append(element)
}
mutating func dequeue() -> T? {
guard head < array.count,
let element = array[head] else { return nil }
array[head] = nil
head += 1
let percentage = Double(head) / Double(array.count)
if percentage > 0.25 && array.count > 50 {
array.removeFirst(head)
head = 0
}
return element
}
var front: T? {
if isEmpty {
return nil
} else {
return array[head]
}
}
}
let nk = readLine()!.split(separator: " ").map { Int($0)! }; let n = nk[0]; let k = nk[1]
var visited: [Int] = .init(repeating: 0, count: 200004) // 두배 고려
var short: [Int] = .init(repeating: 0, count: 200004)
var q = Queue<Int>()
q.enqueue(n)
visited[n] = 1
short[n] = 1
while(!q.isEmpty) {
guard let current = q.front else { break }
_ = q.dequeue()
for next in [current + 1, current - 1, current * 2] {
if next < 0 || next > 100000 {
continue
}
if visited[next] == 0 {
visited[next] = visited[current] + 1
short[next] += short[current]
q.enqueue(next)
} else {
if visited[next] == visited[current] + 1 {
short[next] += short[current]
}
}
}
}
print(visited[k] - 1)
print(short[k])