[Java] 백준 16953 - A -> B

김민성·2022년 8월 19일
0

알고리즘 퀴즈

목록 보기
34/55
post-thumbnail

백준 16953 - A -> B

https://www.acmicpc.net/problem/16953

문제

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

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

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

입력

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

출력

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


해결방법

  • 단순히 문제에서 주어진 대로 A에서부터 B가 될 때까지 연산을 반복하다보면 시간초과가 나버린다.
  • 따라서 연산 과정을 B에서 A로 거꾸로 생각해본다.
    • 짝수라면 2로 나눈다.
    • 1의자리의 수가 1로 끝난다면 1을 뺀다.
  • 불가능한 경우
    • 위의 두 연산이 모두 불가능할 때
    • 연산은 했는데 그 결과가 A보다 작아져 버릴 때
  • 이 때 A와 B를 int 타입이 아닌 long 타입으로 받는 것에 주의하자. 그런데 문제의 제한사항에서는 A와 B가 둘다 10^9 보다 작다고 했는데 왜 long 타입으로 받아야 할까?
    • 이는 연산 과정에서 int 의 범위를 넘어갈 가능성이 있기 때문이다.
    • 예를 들어 A를 10억이라고 가정해보자. 여기서 1을 수의 가장 오른쪽에 추가하는 연산에서 자릿수가 100억이 되기 때문에 int 의 범위를 넘어가버리게 된다.

코드

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

public class Baekjoon_16953 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        long a = Long.parseLong(st.nextToken());
        long b = Long.parseLong(st.nextToken());

        int cnt = 1;

        while (b != a) {
            String bStr = b + "";
            int bLen = bStr.length();

            if (b < a) {
                cnt = -1;
                break;
            }

            if (bStr.charAt(bLen - 1) != '1' && b % 2 != 0) {
                cnt = -1;
                break;
            }

            if (b % 2 == 0) {
                b /= 2;
            } else {
                bStr = bStr.substring(0, bLen - 1);
                b = Long.parseLong(bStr);
            }
            cnt++;
        }

        System.out.println(cnt);

    }
}

0개의 댓글