문제 설명
OO 연구소는 한 번에 K 칸을 앞으로 점프
하거나, (현재까지 온 거리) x 2 에 해당하는 위치로 순간이동
을 할 수 있는 특수한 기능을 가진 아이언 슈트를 개발하여 판매하고 있습니다. 이 아이언 슈트는 건전지로 작동되는데, 순간이동을 하면 건전지 사용량이 줄지 않지만, 앞으로 K 칸을 점프하면 K 만큼의 건전지 사용량이 듭니다. 그러므로 아이언 슈트를 착용하고 이동할 때는 순간 이동을 하는 것이 더 효율적입니다. 아이언 슈트 구매자는 아이언 슈트를 착용하고 거리가 N 만큼 떨어져 있는 장소로 가려고 합니다. 단, 건전지 사용량을 줄이기 위해 점프로 이동하는 것은 최소로 하려고 합니다. 아이언 슈트 구매자가 이동하려는 거리 N이 주어졌을 때, 사용해야 하는 건전지 사용량의 최솟값
을 return하는 solution 함수를 만들어 주세요.
예를 들어 거리가 5만큼 떨어져 있는 장소로 가려고 합니다.
아이언 슈트를 입고 거리가 5만큼 떨어져 있는 장소로 갈 수 있는 경우의 수는 여러 가지입니다.
- 처음 위치 0 에서 5 칸을 앞으로 점프하면 바로 도착하지만, 건전지 사용량이 5 만큼 듭니다.
- 처음 위치 0 에서 2 칸을 앞으로 점프한 다음 순간이동하면 (현재까지 온 거리 : 2) x 2에 해당하는 위치로 이동할 수 있으므로 위치 4로 이동합니다. 이때 1 칸을 앞으로 점프하면 도착하므로 건전지 사용량이 3 만큼 듭니다.
- 처음 위치 0 에서 1 칸을 앞으로 점프한 다음 순간이동하면 (현재까지 온 거리 : 1) x 2에 해당하는 위치로 이동할 수 있으므로 위치 2로 이동됩니다. 이때 다시 순간이동하면 (현재까지 온 거리 : 2) x 2 만큼 이동할 수 있으므로 위치 4로 이동합니다. 이때 1 칸을 앞으로 점프하면 도착하므로 건전지 사용량이 2 만큼 듭니다.
위의 3가지 경우 거리가 5만큼 떨어져 있는 장소로 가기 위해서 3번째 경우가 건전지 사용량이 가장 적으므로 답은 2가 됩니다.
제한사항
- 숫자 N: 1 이상 10억 이하의 자연수
- 숫자 K: 1 이상의 자연수
해결 방법
처음엔 dp로 접근했다.
dp[i] = i까지 오는데 드는 최소 비용
으로 설정해서 거리가 0부터 N일 때까지 전부 다 구하려고 했는데
N이 작으면 문제없었겠지만 이 문제에서는 N이 최대 10억
이기 때문에 10억 크기의 배열을 만들어야되는데 이게 문제였다.
C/C++에서는 함수 내에서 지나치게 큰 배열을 생성할 수 없다. 그래서 배열을 사용하지 않는 방법을 생각해야 됐는데, 그러다 보니 배열이 굳이 필요 없겠다는 생각이 들었다.
이 문제에서는 점프할 때만 건전지가 줄어드므로 무조건 점프보다 순간 이동
을 하는 것이 유리하다. 그럼 가능한 많이 순간 이동을 해야 하는데, 순간 이동은 이전 거리의 2배를 이동하는 것이므로 순간 이동한 후의 위치는 무조건 짝수
여야 한다.
N부터 시작해서 0까지 가는 경우로 생각해보면 더 쉽다.
N이 짝수
라면 순간 이동으로 올 수 있는 위치이기 때문에 N/2
위치로 이동만 한다.(건전지 소모 없음)
만약 N이 홀수
라면 순간 이동으로 올 수 없는 위치이기 때문에 무조건 점프를 해서 와야 한다. 따라서 N-1
로 이동한다.(건전지 하나 소모)
이걸 N이 0이 될때까지 반복하면 된다!
오백 원짜리 동전 몇 개, 백 원짜리 동전 몇 개가 있을 때 가능한 최소 개수로 비용을 지불하는 문제와 동일한 풀이 방법이다.
내 코드
// [12980] 점프와 순간 이동
#include <iostream>
using namespace std;
int solution(int n)
{
int cost = 0;
while(n > 0) {
if(n % 2 == 0) {
n /= 2;
}
else {
cost++;
n--;
}
}
return cost;
}
'프로그래머스 > 구현' 카테고리의 다른 글
[프로그래머스] 기능개발 (0) | 2022.06.29 |
---|---|
2021 KAKAO BLIND RECRUITMENT 신규 아이디 추천 (0) | 2021.09.10 |
[프로그래머스] 키패드 누르기(C++) (0) | 2021.05.03 |