티스토리 뷰
[ BOJ ] 16397번 : 탈출
문제 : https://www.acmicpc.net/problem/16397
[ 문제 ]
홍익이는 홍익대학교 프로그래밍 경진대회의 출제진이다. 홍익이는 새벽에 문제를 만들던 도중 뒤통수에 느껴지는 고통과 함께 정신을 잃었다.
홍익이는 좁은 방에서 눈을 떴다. 주변을 살펴보니 벽면에는 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”을 따옴표 없이 출력한다.
[ 문제 접근 및 풀이 ]
각 값들에 대해서 몇 회 눌렀는지 저장하기 위해 vis 배열을 만들어 주었다.
이후 시작 값인 N을 BFS를 통해서 G를 찾는다.
A 버튼은 N+1을 시켰으며
B 버튼에서 2*N을 시켰을 때 99,999를 넘어가는 지 체크 후,
문자열로 만들어 가장 앞자리의 수를 1 낮춰 주었다.
1 ≤ 문자열에서 가장 앞자리 ≤ 9 이 보장되므로 1을 빼면
0 ≤ 문자열에서 가장 앞자리 - 1 ≤ 8 이 된다.
따라서 다시 정수형으로 바꾸게 된다면 문제 없이 가장 앞자리를 1을 뺄 수 있다.
이후 계속 BFS를 통해 값을 찾다 T회가 지나 값을 찾지 못한다면 ANG을 출력했다.
[ 소스 코드 ]
#include<bits/stdc++.h>
using namespace std;
int N,T,G;
queue<int> q;
int vis[100001];
void Q_16397();
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
Q_16397();
}
void Q_16397(){
cin >> N >> T >> G;
q.push(N);
vis[N] = 1;
while (!q.empty()) {
auto cur = q.front(); q.pop();
if (T < vis[cur] - 1)break;
if (cur == G) {
cout << vis[G] - 1;
return;
}
for (int i = 0; i < 2;i++) {
int x = cur;
if (i == 0) {
x += 1;
}
else {
x *= 2;
if (x > 99999 || x==0) continue;
string A = to_string(x);
A[0] -= 1;
x = stoi(A);
}
if (x > 99999) continue;
if (vis[x])continue;
q.push(x);
vis[x] = vis[cur] + 1;
}
}
cout << "ANG";
}

'BOJ' 카테고리의 다른 글
| [ BOJ / C++ ] 17352번 : 여러분의 다리가 되어 드리겠습니다! (0) | 2025.05.25 |
|---|---|
| [ BOJ / C++ ] 14499번 : 주사위 굴리기 (1) | 2025.05.25 |
| [ BOJ / C++ ] 11725번 : 트리의 부모 찾기 (0) | 2025.05.18 |
| [ BOJ / C++ ] 1991번 : 트리 순회 (0) | 2025.05.18 |
| [ BOJ / C++ ] 1240번 : 노드사이의 거리 (0) | 2025.05.18 |
- Total
- Today
- Yesterday
- 해시를 사용한 집합과 맵
- 시뮬레이션
- 분리 집합
- 순열 사이클 분할
- 정렬
- 다이나믹 프로그래밍
- 그래프 탐색
- 수학
- C++
- 트리에서의 다이나믹 프로그래밍
- 그리디 알고리즘
- 재귀
- 문자열
- 구현
- 깊이 우선 탐색
- 스택
- 그래프
- 파싱
- BOJ
- 백준
- 자료 구조
- 너비 우선 탐색
- 그래프 이론
- 슬라이딩 윈도우
- 브루트포스 알고리즘
- 트리
- 트리를 사용한 집합과 맵
- BFS
- 분할 정복을 이용한 거듭제곱
- 누적 합
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
