ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스][lv2] 점프와 순간이동 Java
    알고리즘 2023. 1. 31. 19:20

    문제 설명

    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 이상의 자연수

    입출력 예

    N result

    5 2
    6 2
    5000 5

    입출력 예 설명

    입출력 예 #1위의 예시와 같습니다.

    입출력 예 #2처음 위치 0 에서 1 칸을 앞으로 점프한 다음 순간이동 하면 (현재까지 온 거리 : 1) x 2에 해당하는 위치로 이동할 수 있으므로 위치 2로 이동합니다. 이때 1 칸을 앞으로 점프하면 위치3으로 이동합니다. 이때 다시 순간이동 하면 (현재까지 온 거리 : 3) x 2 이동할 수 있으므로 위치 6에 도착합니다. 이 경우가 건전지 사용량이 가장 적으므로 2를 반환해주면 됩니다.

    입출력 예 #3위와 같은 방식으로 합니다.

    나만의 풀이 방식

    • 처음에는 pos 변수를 생성하고 pos이 n보다 작을 때까지 루프문을 돌리면서 pos이 n 값과 같아지도록하는 로직을 구현했다.
    • 일단 이 문제는 짝수일 때와 홀수일 때를 구분해야 한다고 생각했다. 짝수일 때는 pos 변수가 n의 약수 값이 되면 끝나는 문제였으므로 n을 2로 나눌 수 있을 때까지 나누고 홀수가 되었을 때, pos을 변경하는 로직을 구현했다.
    • 테스트케이스가 5와 6까지는 정답으로 나왔지만 5000은 그렇지 않았다.
    • 5000을 홀수가 될 때까지 2로 나누면 625란 값이 되는데 그때 내가 구현한 pos으로 문제를 해결하면 114라는 값으로 정답과 거리가 아주 멀었다. 내 로직으로 실행을 하고 출력 결과를 봤을 때 2의 배수인 512 부터 625까지 1씩 더해버리는 문제가 발생했기 때문이다.
    // 틀린 로직
    package programmers.lv2;
    
    import java.util.Scanner;
    
    public class JumpAndTeleport {
        public int solution(int n){
            int answer = 1;
    
            int pos = 1;
    
            while(pos < n){
    
                if(n % 2 == 0){
                    n /= 2;
                }else{
                    if(pos * 2 < n){
                        pos *= 2;
                    }else {
                        pos++;
                        answer++;
                    }
                }
                
            }
    
            return answer;
        }
    
        public static void main(String[] args) {
            JumpAndTeleport T = new JumpAndTeleport();
            Scanner in = new Scanner(System.in);
    
            int n = in.nextInt();
    
            System.out.println(T.solution(n));
        }
    }
    
    • 그래서 꽤 오래 고민하다가 홀수가 나온 상태에서도 2로 나누어버리면 어떨까? 2로 나누면 나머지는 1이 남으니까 그때마다 answer를 더하면 될 것 같은데?라는 생각이 들었다. 그리고 로직으로 구현했다.
    //정답 로직
    package programmers.lv2;
    
    import java.util.Scanner;
    
    public class JumpAndTeleport {
        public int solution(int n){
            int answer = 0;
    
            int pos = 1;
    
            while(n > 1){
                if(n % 2 == 0){
                    n /= 2;
                }else{
                    n /= 2;
                    answer++;
    
                    System.out.println(n + " " + answer);
                }
    
            }
            answer++;
            return answer;
        }
    
        public static void main(String[] args) {
            JumpAndTeleport T = new JumpAndTeleport();
            Scanner in = new Scanner(System.in);
    
            int n = in.nextInt();
    
            System.out.println(T.solution(n));
        }
    }
    
    • 짝수일 때는 2로 나누고, 홀수일 때도 2로 나눈다음 answer를 1씩 증가시켜줬다. 그리고 n이 1보다 클 때까지만 루프문을 돌렸다. 그리고 루프문을 빠져나온 뒤에 answer를 1 증가시켜주어서 남은 n 값인 1 값까지 처리가 되는 것이다.
    • 이를 5000으로 로직의 상세 출력을 보면 아래와 같다.
    n = 2500 answer = 0
    n = 1250 answer = 0
    n = 625 answer = 0
    n = 312 answer = 1
    n = 156 answer = 1
    n = 78 answer = 1
    n = 39 answer = 1
    n = 19 answer = 2
    n = 9 answer = 3
    n = 4 answer = 4
    n = 2 answer = 4
    n = 1 answer = 4
    5 // 루프문을 빠져나온 뒤 answer++;이기 때문에 5가 출력된다.
    
Designed by Tistory.