PS/백준
[BOJ] 백준 16953번 : A -> B (JAVA)
문제의 링크 : https://www.acmicpc.net/problem/16953
문제
정수 A를 B로 바꾸려고 한다. 가능한 연산은 다음과 같은 두 가지이다.
- 2를 곱한다.
- 1을 수의 가장 오른쪽에 추가한다.
A를 B로 바꾸는데 필요한 연산의 최솟값을 구해보자.
풀이
처음에는 BFS로 생각하고, A에서 B로 두 가지 연산을 계속 실시해서 최소의 경우로 B를 도달하는 횟수는 몇 번인지 판단하는 로직을 세웠었습니다. 하지만, B가 10^9로 꽤 큰 값이었고 결국 메모리 초과를 피할 수 없었습니다.
그래서 이것을 반대로 생각해 보았습니다. A에서 B로 만드는 것이 아닌, B에서 A로 만드는 로직이었죠. 전반적인 로직은 다음과 같습니다.
1. B가 2로 나누어 떨어지지 않거나, 맨 끝자리가 1이 아니라면 A로 만드는 것이 불가능하다.
2. B가 2로 나누어 떨어진다면, B를 2로 나눈다.
3. B의 맨 끝자리가 1이라면, 1을 없앤다.
4. 2, 3번 과정이 성립할 때마다 횟수를 1개씩 올리고, 중간에 성립하지 않는 경우가 생기면 반복문을 종료한다.
자세한 소스코드는 아래와 같습니다.
소스 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
long A = Long.parseLong(st.nextToken());
long B = Long.parseLong(st.nextToken());
int ans = 1;
while (B != A) {
if (B < A) {
ans = -1;
break;
}
String str = String.valueOf(B);
// 맨 끝자리가 1이거나 B가 2로 나누어 떨어지지 않는다면, A로 만들 수 없다.
if (str.charAt(str.length() - 1) != '1' && B % 2 != 0) {
ans = -1;
break;
}
if (B % 2 == 0) { // B가 2로 나누어 떨어진다면, 2로 나눈다.
B >>= 1;
} else { // 그렇지 않고, 맨 끝자리가 1이라면 1을 없앤다.
str = str.substring(0, str.length() - 1);
B = Long.parseLong(str);
}
ans++; // 횟수 증가.
}
bw.write(ans + "\n");
bw.flush();
bw.close();
br.close();
}
}
|
cs |
지적 혹은 조언 환영합니다! 언제든지 댓글로 남겨주세요.
'PS > 백준' 카테고리의 다른 글
[BOJ] 백준 1082번 : 방 번호 (JAVA) (1) | 2020.05.11 |
---|---|
[BOJ] 백준 2212번 : 센서 (JAVA) (2) | 2020.05.10 |
[BOJ] 백준 10799번 : 쇠막대기 (JAVA) (0) | 2020.05.07 |
[BOJ] 백준 1475번 : 방 번호 (JAVA) (1) | 2020.05.06 |
[BOJ] 백준 2437번 : 저울 (JAVA) (1) | 2020.05.05 |
댓글