문제 풀이/백준

[백준] 1019번. 책 페이지(JAVA)

27200 2025. 4. 11. 20:09

문제

https://www.acmicpc.net/problem/1019


풀이(30분)

import java.io.*;

public class Main {

    static long[] numCount = new long[10]; // 0부터 9까지 각 숫자의 등장 횟수를 저장할 배열

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine()); // 입력값 N

        int start = 1; // 시작 숫자
        int len = 1;   // 현재 자릿수의 가중치 (1, 10, 100, ...)

        // 시작이 끝보다 작거나 같을 때까지 반복
        while (start <= n) {
            // n의 일의 자리를 9로 만들기 위해 하나씩 줄여가며 카운트
            while (n % 10 != 9 && start <= n) {
                countDigits(n, len); // n의 각 자리 숫자를 세기
                n--;
            }

            // 시작이 끝보다 커졌으면 종료
            if (n < start) break;

            // start의 일의 자리를 0으로 만들기 위해 하나씩 늘리며 카운트
            while (start % 10 != 0 && start <= n) {
                countDigits(start, len); // start의 각 자리 숫자를 세기
                start++;
            }

            // 위 과정을 통해 양 끝이 0과 9로 정렬되었을 경우, 자릿수별로 전체 묶음 계산
            // 예: start = 120, n = 139이면, 120~139 범위를 자릿수만큼 묶어서 계산 가능
            long count = (n / 10 - start / 10 + 1) * len;
            for (int i = 0; i < 10; i++) {
                numCount[i] += count; // 모든 숫자가 동일하게 등장하므로 각 숫자에 count 추가
            }

            // 자릿수 줄이기 (다음 루프에선 10의 자리 → 100의 자리 ...)
            start /= 10;
            n /= 10;
            len *= 10; // 다음 자릿수의 가중치
        }

        // 결과 출력
        for (long c : numCount) {
            System.out.print(c + " ");
        }
    }

    // 하나의 수 x를 받아 각 자리 숫자를 numCount에 더해주는 함수
    static void countDigits(int x, int unit) {
        while (x > 0) {
            numCount[x % 10] += unit; // 해당 자리 숫자에 가중치 unit만큼 추가
            x /= 10; // 다음 자리로 이동
        }
    }
}

문제 풀이 전략

 

자릿수마다 직접적으로 값을 더해주는 방식으로 적용했다.

 

사실 플레 문제치고는 주석에 있는 아이디어로 전부 해결 가능한 것 같다.