본문 바로가기

Algorithm/백준

[백준/JAVA] 🥈 16953번 A → B

문제

정수 A를 B로 바꾸려고 한다. 가능한 연산은 다음과 같은 두 가지이다.

  • 2를 곱한다.
  • 1을 수의 가장 오른쪽에 추가한다. 

A를 B로 바꾸는데 필요한 연산의 최솟값을 구해보자.

입력

첫째 줄에 A, B (1 ≤ A < B ≤ 109)가 주어진다.

출력

A를 B로 바꾸는데 필요한 연산의 최솟값에 1을 더한 값을 출력한다. 만들 수 없는 경우에는 -1을 출력한다.

예제 입출력

 

 

 

풀이

 

1. 이런 문제는 DFS로 풀고 가지치기를 적절하게 쳐내는 것이 좋지 않을까? (완탐)

한 쪽은 X2, 다른 쪽은 X10+1로 가지를 뻗어나가면서 정답일 경우 level+1 출력하면 된다.

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    static int answer=-1;
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(bf.readLine());
        long a = Long.parseLong(st.nextToken());
        long b = Long.parseLong(st.nextToken());
        //System.out.println(bfs());
        dfs(0, a, b);
        System.out.println(answer);
    }
    static void dfs(int L, long a, long b){
        if(a>b) return;
        if(a==b) answer=L+1;
        else {
            dfs(L+1, a*2, b);
            dfs(L+1, a*10+1, b);
        }
    }
}

 

 

 

2. BFS - visited 배열(이미 계산한 숫자인지) 검사X  ==> 시간과 메모리에서 효율적인 코드👍

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    static long a, b;
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(bf.readLine());
        a = Long.parseLong(st.nextToken());
        b = Long.parseLong(st.nextToken());
        System.out.println(bfs());
    }
    static int bfs(){
        int cnt=0;
        Queue<Long> q = new LinkedList<>();
        q.add(a);

        while(!q.isEmpty()){
            int size = q.size();

            for(int i=0; i<size; i++){
                long tmp = q.poll();
                if(tmp==b)
                    return cnt+1;

                if(tmp*2<=b) q.add(tmp*2);
                if(tmp*10+1<=b) q.add(tmp*10+1);
            }
            cnt++;
        }
        return -1;
    }
}

 

 

 

3. BFS - visited 배열(이미 계산한 숫자인지) 검사

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(bf.readLine());
        long A = Long.parseLong(st.nextToken());
        long B = Long.parseLong(st.nextToken());
        System.out.println(BFS(A, B));
    }

    static int BFS(long start, long end){
        int count=0;
        Queue<Long> Q = new LinkedList<>();
        boolean[] visited = new boolean[(int) (end+1)];
        Q.add(start);
        visited[(int)start]=true;

        while(!Q.isEmpty()){
            int len = Q.size();
            for (int i = 0; i < len; i++) {
                long cur = Q.poll();
                if(cur==end) return count+1;

                //1번 연산. X2
                long tmp = cur*2;
                if(tmp <=end && !visited[(int)tmp]){
                    visited[(int)tmp]=true;
                    Q.add(tmp);
                }

                //2번 연산. X10 +1
                tmp = cur*10+1;
                if(tmp <=end && !visited[(int)tmp]){
                    visited[(int)tmp]=true;
                    Q.add(tmp);
                }
            }
            count++;
        }
        return -1;
    }
}

 

 

 

 

 

다른 풀이

https://waristo.tistory.com/48

 

[백준 16953] A → B with JAVA

www.acmicpc.net/problem/16953 16953번: A → B 첫째 줄에 A, B (1 ≤ A < B ≤ 109)가 주어진다. www.acmicpc.net 문제 정수 A를 B로 바꾸려고 한다. 가능한 연산은 다음과 같은 두 가지이다. 2를 곱한다. 1을 수의 가장

waristo.tistory.com

 

 

https://jaewoo2233.tistory.com/74

 

백준 No.16953 A->B (JAVA)

문제 정수 A를 B로 바꾸려고 한다. 가능한 연산은 다음과 같은 두 가지이다. - 2를 곱한다. - 1을 수의 가장 오른쪽에 추가한다. A를 B로 바꾸는데 필요한 연산의 최솟값을 구해보자 2 162 풀이 - A가 B

jaewoo2233.tistory.com