CodingTest
숫자 변환하기
흑조롱이
2025. 3. 31. 07:48
https://school.programmers.co.kr/learn/courses/30/lessons/154538
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
1. 개요
큐에 (연산을 가했을 때의 숫자, 그 숫자에 도달하기 까지 필요한 연산 횟수)를 저장하고, 이를 순회하며 목표치에 도달한 경우가 있는 지 확인하는 것이 이 문제의 골자이다.
2. 알고리즘 및 풀이
1) 변수 초기화
int ans = -1;
queue<vector<int>> que; // 숫자, 그 숫자에 도달하기 까지의 연산 횟수를 저장
que.push({x, 0}); // 큐 초기화
set<int> visited; // 봤던 숫자를 저장
숫자와 연산횟수를 자장하기 위한 큐, 방문한 숫자들을 기록하기 위한 set을 초기화 한다.
set은 기록한 숫자들을 확인할 때의 시간복잡도를 줄이기 위해 vector 대신 사용한다.
2) 큐 순회
while (!que.empty()) {
vector<int> que_top = que.front(); // 맨 앞의 원소 가져오기
que.pop();
int cur = que_top[0];
int cnt = que_top[1];
if (y < cur || visited.count(cur) > 0) { // 목표를 지나쳤거나, 이미 본 적이 있는 숫자면
continue; // 무시
}
visited.insert(cur); // 현재 숫자를 확인했다고 표시
if (cur == y) { // 목표 도달
ans = cnt; // 답 설정
break; // 반복문 탈출
}
else { // 도달하지 못했다면
vector<int> candid = {cur*2, cur*3, cur+n};
for (int i = 0; i < 3; i++) { // 3가지 경우 순회
if (candid[i] <= y && visited.count(candid[i]) == 0) { // 보는 숫자가 목표 이하이고, 방문한 적이 없다면
que.push({candid[i], cnt+1}); // 나중에 보기 위해, 큐에 저장
}
}
}
}
(1) 목표를 지나쳤거나, 이전에 본 적 있는 숫자인지 확인
목표치를 지나쳤거나, 이미 방문한 시점에서는 더 이상 볼 이유가 없으므로, 무시한다.
(2) 본 적이 있는 숫자로 기록
visited에 현재 숫자를 넣음으로써, 해당 숫자를 본 적이 있다고 표시한다.
(3) 목표에 도달했는 지 확인
답안은 여기까지 오는데 필요한 연산 횟수이다.
따라서 ans의 값을 cnt의 값으로 바꾸고, 반복문을 탈출한다.
(4) 목표에 도달하지 못했다면
3가지 연산을 수행하는 경우 별 값과 연산횟수를 계산하고, 이를 큐에 넣는다.
3. 전체 소스코드
// C++
#include <string>
#include <vector>
#include <queue>
#include <set>
using namespace std;
int solution(int x, int y, int n) {
// 1)
int ans = -1;
queue<vector<int>> que;
que.push({x, 0});
set<int> visited;
// 2)
while (!que.empty()) {
vector<int> que_top = que.front();
que.pop();
int cur = que_top[0];
int cnt = que_top[1];
// (1)
if (y < cur || visited.count(cur) > 0) {
continue;
}
// (2)
visited.insert(cur);
// (3)
if (cur == y) {
ans = cnt;
break;
}
// (4)
else {
vector<int> candid = {cur*2, cur*3, cur+n};
for (int i = 0; i < 3; i++) {
if (candid[i] <= y && visited.count(candid[i]) == 0) {
que.push({candid[i], cnt+1});
}
}
}
}
return ans;
}
# Python3
from collections import deque
def solution(x, y, n):
# 1)
ans = -1
que = deque()
que.append((x, 0))
visited = set()
# 2)
while que:
cur, cnt = que.popleft()
# (1)
if y < cur or cur in visited:
continue
# (2)
visited.add(cur)
# (3)
if cur == y:
ans = cnt
break
# (4)
else:
for candid in (cur * 2, cur * 3, cur + n):
if candid <= y and candid not in visited:
que.append((candid, cnt + 1))
return ans