마법의 엘리베이터

하이솝·2026년 7월 7일

2026.07.07

문제 풀이

1차 실행 오류


38.5/100

99와 같이 n = 9일 때, x = 90, y = 100과 같이
자릿수가 올라가는 경우를 고려하지 않음

class Solution {
    public int solution(int storey) {
        int result = 0;
        int dividend = 1;
        int digit = 0;
        while(true) { // storey가 몇자리수인지 계산
            if (storey / dividend == 0) {
                break;
            }
            dividend *= 10;
            digit++;
        }
        dividend = (int)Math.round(Math.pow(10, digit - 1));
        while(true) {
            int n = storey / dividend;
            int x = n * dividend;
            int y = (n + 1) * dividend;
            if (storey - x > y - storey) {
                storey = y - storey;
                result = result + n + 1;
            }
            else {
                storey = storey - x;
                result = result + n;
            }
            dividend /= 10;
            
            if (dividend == 1) {
                result += storey;
                break;
            }
        }
        
        return result;
    }
}

2차 실행 오류


53.8/100

56의 경우 코드로 진행하게 되면 10이 나오는 반면,
실제 정답은 -100(1), 40(4), 4(4)로 9이다.

1의 자리 버튼을 10번 이상 누르게 되면 10의 자리에 영향을 줌
그 반대로 10의 자리를 아무리 눌러봤자 1의 자리에는 영향을 주지 않음

아래-위 관계인 것을 알 수 있으며,
상위 자리부터 판별하는 것이 아닌, 하위 자릿수부터 판별해야 함


class Solution {
    public int solution(int storey) {
        int result = 0;
        int dividend = 1;
        int digit = 0;
        
        while(true) { // storey가 몇자리수인지 계산
            if (storey / dividend == 0) {
                break;
            }
            dividend *= 10;
            digit++;
        }
        
        dividend = (int)Math.round(Math.pow(10, digit - 1));
        while(true) {
            int n = storey / dividend;
            int x = n * dividend;
            int y = (n + 1) * dividend;
            if (storey - x > y - storey) {
                storey = y - storey;
                result = ((n + 1) < 10 ? (result + n + 1) : (result + 1));
            }
            else {
                storey = storey - x;
                result = result + n;
            }
            dividend /= 10;
            
            if (dividend == 1) {
                result += storey;
                break;
            }
        }
        
        return result;
    }
}

3차 실행 오류


46.2/100

최상단 자릿수를 고려하지 않고 그냥 더해버림


class Solution {
    public int solution(int storey) {
        int result = 0;
        int dividend = 1;
        int digit = 0;
        
        while(true) { // storey가 몇자리수인지 계산
            if (storey / dividend == 0) {
                break;
            }
            dividend *= 10;
            digit++;
        }
        
        dividend = (int)Math.round(Math.pow(10, digit - 1));
        int[] digits = new int[digit];
        for (int i = 0; i < digit; i++) {
            digits[i] = storey / dividend;
            storey = storey % dividend;
            dividend /= 10;
        }
        
        for (int i = digit - 1; i >= 0; i--) {
            if (digits[i] > 5 && i > 0) {
                digits[i - 1] += 1;
                result = result + 10 - digits[i];
            }
            else {
                result = (digits[i] < 10 ? (result + digits[i]) : (result + 1));
            }
        }
        
        return result;
    }
}

4차 실행 오류


76.9/100

현재 자릿값이 정확히 5일 때, 높은 자릿수가


class Solution {
    public int solution(int storey) {
        int result = 0;
        int dividend = 1;
        int digit = 0;
        
        while(true) { // storey가 몇자리수인지 계산
            if (storey / dividend == 0) {
                break;
            }
            dividend *= 10;
            digit++;
        }
        
        dividend = (int)Math.round(Math.pow(10, digit - 1));
        int[] digits = new int[digit];
        for (int i = 0; i < digit; i++) {
            digits[i] = storey / dividend;
            storey = storey % dividend;
            dividend /= 10;
        }
        
        for (int i = digit - 1; i >= 0; i--) {
            if (digits[i] > 5) {
                if (i == 0) {
                    result = result + 10 - digits[i] + 1;
                }
                else {
                    digits[i - 1] += 1;
                    result = result + 10 - digits[i];
                }
            }
            else {
                result = result + digits[i];
            }
        }
        
        return result;
    }
}

5차 실행 오류


84.6/100

연속적으로 5가 나오는 경우에 대한 경우


class Solution {
    public int solution(int storey) {
        int result = 0;
        int dividend = 1;
        int digit = 0;
        
        while(true) { // storey가 몇자리수인지 계산
            if (storey / dividend == 0) {
                break;
            }
            dividend *= 10;
            digit++;
        }
        
        dividend = (int)Math.round(Math.pow(10, digit - 1));
        int[] digits = new int[digit];
        for (int i = 0; i < digit; i++) {
            digits[i] = storey / dividend;
            storey = storey % dividend;
            dividend /= 10;
        }
        
        for (int i = digit - 1; i >= 0; i--) {
            if (digits[i] > 5) {
                if (i == 0) {
                    result = result + 10 - digits[i] + 1;
                }
                else {
                    digits[i - 1] += 1;
                    result = result + 10 - digits[i];
                }
            }
            else if (digits[i] == 5 && i != 0) {
                if (digits[i - 1] > 5) {
                    digits[i - 1] += 1;
                    result = result + 10 - digits[i];
                }
                else {
                    result = result + digits[i];
                }
            }
            else {
                result = result + digits[i];
            }
        }
        
        return result;
    }
}

AI 코드

소요 시간: 2시간 15분


코드를 설계하는 과정과 구현은 스스로 했음
이후 실행 오류가 생기면 AI에게 어느 부분이 오류인지 물어보고,
해당 부분을 직접 구현하는 형태로 코드를 작성함


해당 코드는 DP를 이용해서 해결했는데,
DP란 큰 문제들을 작은 문제들로 쪼개고, 그 하위 문제의 답을 저장해뒀다가
재사용해서 문제를 해결하는 방식임


결국 많은 문제를 다양한 알고리즘으로 풀어가며
실력을 키워 나가는 과정은 처음 보는 알고리즘도 있을 것이고,
난해한 코드들도 정말 많을 것이다.

이 문제의 AI가 작성해 준 코드를 해석하는데만 해도 어려웠다.
정답률 50%대에 진입한 후로 점점 문제를 해결하기가 어려워지고 있지만,
자신감을 잃지 않고 모르는 문제는 답을 봐도 코드는 반드시 이해하고 간다는
마음가짐으로 임해야겠다.


class Solution {
    public int solution(int storey) {
        final int INF = Integer.MAX_VALUE / 2;

        int noCarry = 0;      // 자리올림 없이 여기까지 처리했을 때의 최소 비용
        int withCarry = INF;  // 자리올림을 받은 채로 여기까지 처리했을 때의 최소 비용 (1의 자리는 자리올림 받을 수 없으니 처음엔 불가능 상태)

        while (storey > 0) {
            int d = storey % 10;
            storey /= 10;

            int newNoCarry = noCarry + d;              // 자리올림 없이 왔다가, 이번 자리도 내림
            int newWithCarry = noCarry + (10 - d);      // 자리올림 없이 왔다가, 이번 자리는 올림(다음 자리에 넘김)

            if (withCarry < INF) {
                int eff = d + 1; // 아래에서 자리올림을 받았다고 가정한 실질 값
                if (eff < 10) {
                    newNoCarry = Math.min(newNoCarry, withCarry + eff);
                    newWithCarry = Math.min(newWithCarry, withCarry + (10 - eff));
                } else { // d == 9 이면 eff == 10, 자리올림이 강제 확정되고 비용은 0
                    newWithCarry = Math.min(newWithCarry, withCarry);
                }
            }

            noCarry = newNoCarry;
            withCarry = newWithCarry;
        }

        return Math.min(noCarry, withCarry + 1); // 맨 끝에 자리올림이 남아있으면 새 자리 하나 값(1)을 더 지불
    }
}

0개의 댓글