https://www.acmicpc.net/problem/16953
16953번: A → B
첫째 줄에 A, B (1 ≤ A < B ≤ 109)가 주어진다.
www.acmicpc.net
1. 어떤 문제로 이해 했는가? 그리고 문제의 제약 조건은?
정수 A와 B가 주어졌을 때 A를 B로 바꿀 수 있는 연산의 최소 횟수를 구하는것.
연산
- 2를 곱한다.
- 1을 수의 가장 오른쪽에 추가한다.
2. 나의 방식대로 문제를 재정의 하자.
연산 방법
- 2를 곱한다. --> 연산결과 : A * 2
- 1을 수의 가장 오른쪽에 추가한다. --> 연산결과 : A*10 + 1
A를 B로 만들기 위해서 연산1,2 중 하나를 선택하여 연산했을 때 최소횟수를 구한다.
3. 어떤 알고리즘과 자료구조를 사용할 것인가?
bfs와 그리디 방식으로 문제를 풀 수 있다.
그리디 방식으로는 B로 만들기위해서 A를 증가시키는것이 아니라 B를 감소시키는 방식으로 로직을 짠다.
1. B가 A와 2의배수일 때 (B%2 == 0) B/=2해줌
2. B의 마지막 숫자가 1이 될때 (B%10 == 1) B/=10해줌
bfs 방식으로는 A를 연산시키며 깊이우선 탐색하고, A==B일때의 깊이값을 저장한 후 return한다.
4. 어떻게 계산할 것인가?
1) 입력
BufferedReader 사용
5. 주의할 점은 무엇인가?
입력값의 범위가 1<=A<=B<=10^9이므로 int형으로는 저장할 수 없다. long 사용
6. 풀이 과정
1) dfs
import java.io.*;
import java.util.StringTokenizer;
public class Main {
static int result = -1;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
long A = Integer.parseInt(st.nextToken());
long B = Integer.parseInt(st.nextToken());
dfs(A, B, 0);
bw.write(result + "\n");
bw.flush();
br.close();
bw.close();
}
static void dfs(long A, long B, int depth) {
if (A > B) {
return;
}
if (A == B) {
result = depth + 1;
return;
}
dfs(A*2, B, depth+1);
dfs(A*10+1, B, depth+1);
return;
}
}
재귀함수를 사용한다. A*2와 A*10+1연산을 하는 모든 경우를 탐색하고, A==B일때의 깊이값을 전역변수인 result에 저장한다. 그리고 A>B일경우는 더이상 A와 B가 같아질 수 없으므로 저장하지 않고 리턴한다.
2) 그리디
import java.io.*;
import java.util.StringTokenizer;
public class Main {
static int result = -1;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
long A = Integer.parseInt(st.nextToken());
long B = Integer.parseInt(st.nextToken());
int depth = 0;
while (A <= B) {
if (A == B) {
result = depth+1;
break;
}
if (B % 10 == 1) {
B /= 10;
} else if (B % 2 == 0) {
B /= 2;
} else {
result = -1;
break;
}
depth += 1;
}
bw.write(result + "\n");
bw.flush();
br.close();
bw.close();
}
}
7. 개선점
그리디 알고리즘 조건을 단순하게 생각해서 설계해야함
'코딩테스트' 카테고리의 다른 글
[백준 1921번] 정수 삼각형 (0) | 2021.07.12 |
---|---|
[백준 11052번] 카드 구매하기 (0) | 2021.07.11 |
[백준 2579번] 계단 오르기 (0) | 2021.07.04 |
[백준 10870번] 피보나치 수 5 (0) | 2021.07.04 |
[백준 1149번] RGB거리 (0) | 2021.07.04 |