알고리즘/문제 풀이
9019번: DSLR
Themion
2021. 12. 28. 11:07
https://www.acmicpc.net/problem/9019
9019번: DSLR
네 개의 명령어 D, S, L, R 을 이용하는 간단한 계산기가 있다. 이 계산기에는 레지스터가 하나 있는데, 이 레지스터에는 0 이상 10,000 미만의 십진수를 저장할 수 있다. 각 명령어는 이 레지스터에
www.acmicpc.net
각 수를 노드, 연산을 통해 수를 변환하는 것을 에지라고 하면 이 문제는 노드 A에서 노드 B로의 최단 경로를 찾는 문제이다. 따라서 각 노드를 방문했는지 여부와 직전 노드, 그리고 연산 종류를 저장하는 클래스 node를 생성한 뒤 bfs를 통해 최단 경로를 찾고, 탐색한 경로를 순서대로 출력하면 정답이 된다.
#include <cstdio>
#include <queue>
#include <stack>
using namespace std;
#define MAX 10000
// node[i]: 노드 i로 가는 최단 경로에서,
// start: i 직전의 수
// cmd: start를 i로 변환할 명령어
// visit: i가 이전에 나왔다면 true, 아니라면 false
class node {
public:
int start;
char cmd;
bool visit;
node() {
start = 0;
cmd = '\0';
visit = false;
}
node(int _start, char _cmd) {
start = _start;
cmd = _cmd;
visit = true;
}
};
void test_case() {
// A, B: 경로의 시작과 끝, item: 명령어를 통해 A를 변환시킨 모습
int A, B, item[4];
// D, S, L, R 네 명령어 문자
char dslr[5] = "DSLR";
// 각 수의 변환 관계를 나타낼 그래프
node n[MAX];
// bfs에 사용할 큐
queue<int> q;
// s: B에서 A까지 탐색을 스택으로 저장해 출력
stack<char> s;
// 문제 조건을 입력받은 뒤
scanf("%d %d", &A, &B);
// 루트 노드인 A를 q에 push
q.push(A); n[A] = node(A, '\0');
// q에서 노드 하나를 가져와 DSLR 변환
while (!n[B].visit) {
A = q.front(); q.pop();
item[0] = (A * 2) % MAX;
item[1] = (A + (MAX - 1)) % MAX;
item[2] = (A % (MAX / 10)) * 10 + (A / (MAX / 10));
item[3] = (A % 10) * (MAX / 10) + A / 10;
// 변환한 수 중 등장하지 않은 수가 있다면 방문하고 q에 push
for (int i = 0; i < 4; i++) if (!n[item[i]].visit) {
n[item[i]] = node(A, dslr[i]);
q.push(item[i]);
}
}
// B에 도착한 이후 탐색을 통해 A -> B 경로를 스택에 저장
while (n[B].cmd != '\0') {
s.push(n[B].cmd);
B = n[B].start;
}
// 스택에 저장된 경로를 차례로 출력
while (!s.empty()) {
printf("%c", s.top());
s.pop();
} printf("\n");
}
int main() {
int T;
// 테스트 케이스의 수를 입력받고 각 테스트 케이스를 실행
for (scanf("%d%*c", &T); T--;) test_case();
return 0;
}