문제
정수 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
https://jaewoo2233.tistory.com/74
'Algorithm > 백준' 카테고리의 다른 글
[백준/JAVA] 🥇 2363번 치즈 (1) | 2023.12.16 |
---|---|
[백준/JAVA] 🥇 10026번 적록색약 (0) | 2023.12.15 |
[백준/JAVA] 🥈 15650번 N과 M (2) (0) | 2023.12.14 |
[백준/JAVA] 🥈 2644번 촌수계산 (0) | 2023.12.10 |
[백준/JAVA] 🥈 7562번 나이트의 이동 (1) | 2023.12.10 |