본문 바로가기

백준 PS일지/DFS&BFS

[백준/Swift] 12852 : 1로 만들기 2

728x90

 

 


12852 : 1로 만들기 2 / 문제 소개

 

문제

정수 X에 사용할 수 있는 연산은 다음과 같이 세 가지 이다.

  1. X가 3으로 나누어 떨어지면, 3으로 나눈다.
  2. X가 2로 나누어 떨어지면, 2로 나눈다.
  3. 1을 뺀다.

정수 N이 주어졌을 때, 위와 같은 연산 세 개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오!


출력

첫째 줄에 연산을 하는 횟수의 최솟값을 출력한다.

둘째 줄에는 N을 1로 만드는 방법에 포함되어 있는 수를 공백으로 구분해서 순서대로 출력한다. 정답이 여러 가지인 경우에는 아무거나 출력한다.


풀이 과정

 

이 문제는 dp문제라고 분류가 되어있는데 그냥 bfs처럼 풀었다.

N을 1로 만드는 최소한의 연산 횟수, 연산 3가지. (bfs문제 아닌가?!)

 

N이라는 문자에서 연산 과정에 따라 1이 되기 전까지 최소한의 연산 개수를 증가시켜가면서, 연산 과정에 따라 측정되는 값도 저장해가면서 문제를 풀었다.


코드 구현

 

import Foundation

func bfs(_ n: Int)
{
    // n : 탐색할 숫자, "\(n) " 연산처리된 숫자, 0 : 누적 연산 횟수
    var queue = [(n,"\(n) ",0)]
    // queue에 저장될 숫자를 중복 방문하지 않게 하기 위한 visited 체크
    var visited = Array(repeating: false , count : n+1)
    visited[n] = true
    var index = 0
    //연산 횟수 측정하기 위한 변수
    var curCnt = 0
    while index != queue.count
    {
        let (num,ans,count) = queue[index]
        if num == 1
        {
            print(count)
            print(ans)
            return
        }
        if curCnt == count
        {
            curCnt += 1
        }
        index += 1
        if num % 3 == 0 && num / 3 >= 1 && !visited[num/3]
        {
            visited[num/3] = true
            queue.append((num/3,ans+"\(num/3) ",count+1))
        }
        if num % 2 == 0 && num / 2 >= 1 && !visited[num/2]
        {
            visited[num/2] = true
            queue.append((num/2,ans+"\(num/2) ",count+1))
        }
        if num-1 >= 1 && !visited[num-1]
        {
            visited[num-1] = true
            queue.append((num-1,ans+"\(num-1) ",count+1))
        }
    }
}
func BOJ_12852()
{
    let n = Int(readLine()!)!
    bfs(n)
}
BOJ_12852()

 

visit my github

 

728x90