문제
홍익이는 홍익대학교 프로그래밍 경진대회의 출제진이다. 홍익이는 새벽에 문제를 만들던 도중 뒤통수에 느껴지는 고통과 함께 정신을 잃었다.
홍익이는 좁은 방에서 눈을 떴다. 주변을 살펴보니 벽면에는 LED로 된 다섯 자리 십진수 N이, 그 옆에 T, G라는 알파벳과 함께 또 다른 정수 두 개가 쓰여 있었고, 벽 앞에는 버튼 A, B 두 개가 있었다.
버튼을 이리저리 눌러보던 똑똑한 홍익이는 어떻게 해야 방을 탈출할 수 있을지 금방 눈치챘다.
버튼과 수에 대해 홍익이가 알아낸 것은 다음과 같다.
- 버튼 A를 누르면 N이 1 증가한다.
- 버튼 B를 누르면 N에 2가 곱해진 뒤, 0이 아닌 가장 높은 자릿수의 숫자가 1 줄어든다. 예를 들어 123→146으로, 5→0으로, 3→5로 변한다. 단, N이 0이면 버튼 B를 눌러도 수가 변하지 않는다.
- LED가 다섯 자리까지밖에 없기 때문에 N이 99,999를 넘어가는 순간 탈출에 실패하게 된다.
- 버튼 B를 눌러 N에 2를 곱한 순간 수가 99,999를 넘어간다면, 높은 자릿수의 수를 1 낮췄을때 99,999를 넘지 않는다고 해도 탈출에 실패하게 된다.
또한 홍익이는 최대 T회 버튼을 누를 수 있고, 그 횟수 안에 LED로 표현된 N을 G와 같게 만들어야 탈출할 수 있다는 사실을 알아냈다.
똑똑한 홍익이는 이와중에 자존심이 발동해 버튼 누르는 횟수를 최소로 하여 방을 탈출하기로 했다.
홍익이의 방 탈출을 기원하며, 탈출에 필요한 최소의 버튼 횟수를 구하자.
입력
첫 번째 줄에 N (0 ≤ N ≤ 99,999), T (1 ≤ T ≤ 99,999), G (0 ≤ G ≤ 99,999)가 공백 하나를 사이에 두고 주어진다.
각각 N은 LED로 표현된 수, T는 버튼을 누를 수 있는 최대 횟수, G는 탈출을 위해 똑같이 만들어야 하는 수를 뜻한다.
출력
첫 번째 줄에 탈출에 필요한 최소의 버튼 횟수를 출력한다.
만약 탈출할 수 없다면 “ANG”을 따옴표 없이 출력한다.
풀이
BFS를 이용하여 해당 수까지 몇 번만에 도달할 수 있는지를 구하면 된다.
버튼 A의 경우에는 N + 1이 99,999 이하라면 이동이 가능하다.
버튼 B의 경우에는 N * 2가 99,999 이하라면 이동이 가능한데, 이 때 N * 2에서 가장 큰 차수의 수를 1 감소한 값으로 이동한다.
이 부분을 cmath 헤더 파일 내의 log10 함수를 이용하여 구현하였다.
log10(n)을 int로 형 변환해준 수를 X라고 하자. 이 때, pow 함수를 이용하여 pow(10,X)를 N * 2에서 빼주면 된다.
코드
#include <iostream>
#include <string>
#include <queue>
#include <cmath>
using namespace std;
int N, T, G;
void input();
int solve();
queue<pair<int, int>> q; // 현재 숫자, 횟수
bool visit[100000] = { false, };
int main() {
int res = solve();
if (res == -1)
cout << "ANG\n";
else
cout << res << "\n";
return 0;
}
void input() {
cin >> N >> T >> G;
visit[N] = true;
q.push(make_pair(N, 0));
}
int solve() {
input();
while (!q.empty()) {
int cur = q.front().first;
int count = q.front().second;
q.pop();
if (count > T)
continue;
if (cur == G)
return count;
if (cur + 1 <= 99999 && !visit[cur+1]) {
q.push(make_pair(cur + 1, count + 1));
visit[cur + 1] = true;
}
if (cur * 2 <= 99999) {
int minus = pow(10, (int)log10(cur * 2));
int next = cur * 2 - minus;
if (!visit[next]) {
q.push(make_pair(next, count + 1));
visit[next] = true;
}
}
}
return -1;
}
'Old > 백준' 카테고리의 다른 글
백준 10867번 중복 빼고 정렬하기 // C++ (0) | 2020.04.22 |
---|---|
백준 1406번 에디터 // C++ (0) | 2020.04.22 |
백준 5427번 불 // C++ (0) | 2020.03.18 |
백준 6593번 상범 빌딩 // C++ (0) | 2020.03.18 |
백준 8972번 미친 아두이노 // C++ (0) | 2020.03.18 |