BOJ-9019 DSLR
https://www.acmicpc.net/problem/9019
문제 소개
테스트 케이스의 개수 T가 주어지고 각 테스트 케이스마다 두 개의 정수 A와 B가 주어진다.
네 개의 명령어 D, S, L, R을 이용하여 정수 A를 B로 변환하는 최소한의 명령어 나열을 구한다.
정수 n에 대한 각 명령어의 효과는 아래와 같다.
- D : n을 두 배로 바꾼다. 결과 값이 9999 보다 큰 경우에는 10000 으로 나눈 나머지를 취한다.(2n mod 10000)
- S : n - 1을 레지스터에 저장한다. n이 0 이라면 9999가 된다.
- L : n의 각 자릿수를 왼편으로 회전시킨다.
- R : n의 각 자릿수를 오른편으로 회전시킨다.
문제 풀이
bfs로 풀이하였다. 큐 q
의 원소는 pair<int, string>
의 형태를 가지는데, [n, n까지 도달하기 위한 연산]
의 의미이다.
current_num
(현재 수)에 대한 4가지 연산의 결과값인 t
를 연산 후 visited
(방문 여부)를 확인하여 방문하지 않았다면 q
에 push하고 방문 처리한다.
만약 t
가 목표값인 B와 일치한다면 누적된 연산을 출력하고 break한다.
L과 R 명령어는 나누기와 나머지 연산을 이용하여 구현하였다.
각 테스트 케이스가 끝난 후에는 전역으로 선언된 visited
를 memset
으로 다시 초기화해주었다.
코드
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <string>
#include <queue>
#include <memory.h>
bool visited[10000] = { false };
void bfs(int start, int target) {
std::queue<std::pair<int, std::string>> q;
q.push({ start, "" });
visited[start] = true;
while (!q.empty()) {
int current_num = q.front().first;
std::string current_op = q.front().second;
q.pop();
int t;
// D
t = current_num * 2 % 10000;
if (!visited[t]) {
if (t == target) {
std::cout << current_op + "D" << "\n";
break;
}
q.push({ t, current_op + "D" });
visited[t] = true;
}
// S
if (current_num == 0) {
t = 9999;
}
else {
t = current_num - 1;
}
if (!visited[t]) {
if (t == target) {
std::cout << current_op + "S" << "\n";
break;
}
q.push({ t, current_op + "S" });
visited[t] = true;
}
// L
t = current_num % 1000 * 10 + current_num / 1000;
if (!visited[t]) {
if (t == target) {
std::cout << current_op + "L" << "\n";
break;
}
q.push({ t, current_op + "L" });
visited[t] = true;
}
// R
t = current_num % 10 * 1000 + current_num / 10;
if (!visited[t]) {
if (t == target) {
std::cout << current_op + "R" << "\n";
break;
}
q.push({ t, current_op + "R" });
visited[t] = true;
}
}
}
int main() {
using namespace std;
cin.tie(NULL);
ios_base::sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
int a, b;
cin >> a >> b;
bfs(a, b);
memset(visited, false, sizeof(visited));
}
return 0;
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.