Algorithm

백준 1065 : 한수(자바)

KeepLearn 2024. 7. 30. 22:36

문제 바로 가기

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

 

접근 방법

한수의 규칙을 적용할 수 있는 함수를 하나 생성해서 그대로 구현하면 된다. 다만, 한수의 규칙을 생각해 보면 1 이상 100 미만의 숫자는 모두 한수에 해당하고 해당 범위 사이의 숫자를 입력받는다면 해당 숫자가 한수의 개수가 된다. 이 점을 고려하면 계산 과정을 조금은 줄일 수 있다.

 

Step 1.

한수를 구하는 함수인 isArithmeticSequence를 구현하지 않고 단순히 정의만 해둔 상태에서 위에서 다룬 로직을 구현한다.

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int count;
int answer;
int number = Integer.parseInt(br.readLine());

// 99까지는 모두 한수에 해당된다.
if (number < 100) {
    answer = number;
} else {
    // 100이상인 수라면 99까지는 모두 한수이기 때문에 count 값을 99부터 시작한다.
    count = 99;
    for (int i = 100; i <= number; i++) {
        if (isArithmeticSequence(i)) {
            count++;
        }
    }
    answer = count;
}
bw.write(String.valueOf(answer));
bw.close();
br.close();

언제나 그렇듯 BufferedReader와 BufferedWriter는 기본으로 깔아준 뒤, 로직을 작성했다.

99까지는 모두 한수에 해당하기 때문에 입력받은 숫자를 그대로 출력할 수 있도록 하고, 100 이상인 수라면 count 값을 초깃값으로 99를 설정한 뒤, 한수에 해당하는 숫자를 찾으면 count 값을 증가시켜 준다.

구하려는 값이 count이기 때문에 count를 출력해 주면 된다.

여기서, 100 이상의 숫자 중 가장 첫 번째로 나오는 한수는 111이기 때문에 else 구문 밑에서 i = 111부터 시작하면 계산 과정을 조금 더 줄일 수 있지만 유의미할 정도의 최적화는 아니므로 100부터 for문을 돌 수 있도록 처리했다.

 

Step 2.

한수를 구하는 함수인 isArithmeticSequence를 작성한다.

public static boolean isArithmeticSequence(int number) {
    String strNum = Integer.toString(number);
    int len = strNum.length();
    int[] digits = new int[len];

    // 각 자리수를 배열에 저장한다.
    for (int i = 0; i < len; i++) {
        // 유니코드 값의 차이를 활용해서 실제 숫자를 각 배열의 자리에 삽입
        digits[i] = strNum.charAt(i) - '0';
    }

    // 자리수를 순서대로 비교
    int diff = digits[1] - digits[0];
    for (int i = 1; i < len - 1; i++) {
        if (digits[i + 1] - digits[i] != diff) {
            return false;
        }
    }
    return true;
}

입력받은 숫자를 문자열로 만들어 길이를 구한 뒤, 길이만큼의 배열 digits를 생성해서 각 자리 수의 값을 배열에 삽입한다.

이때 유니코드 값의 차이를 활용해서 실제 숫자를 각 배열의 자리에 삽입할 수 있도록 character 형태의 각 자릿수에서 문자 '0' 을 빼는 작업을 한다.

각 자릿수를 순서대로 비교해서 모든 차이(diff)가 같다면 true를 반환하고, 그렇지 않다면 false를 반환하도록 한다.

 

전체 코드

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        int count;
        int answer;
        int number = Integer.parseInt(br.readLine());

        // 99까지는 모두 한수에 해당된다.
        if (number < 100) {
            answer = number;
        } else {
            // 100이상인 수라면 99까지는 모두 한수이기 때문에 count 값을 99부터 시작한다.
            count = 99;
            for (int i = 100; i <= number; i++) {
                if (isArithmeticSequence(i)) {
                    count++;
                }
            }
            answer = count;
        }
        bw.write(String.valueOf(answer));
        bw.close();
        br.close();
    }


    public static boolean isArithmeticSequence(int number) {
        String strNum = Integer.toString(number);
        int len = strNum.length();
        int[] digits = new int[len];

        // 각 자리수를 배열에 저장한다.
        for (int i = 0; i < len; i++) {
            // 유니코드 값의 차이를 활용해서 실제 숫자를 각 배열의 자리에 삽입
            digits[i] = strNum.charAt(i) - '0';
        }

        // 자리수를 순서대로 비교
        int diff = digits[1] - digits[0];
        for (int i = 1; i < len - 1; i++) {
            if (digits[i + 1] - digits[i] != diff) {
                return false;
            }
        }
        return true;
    }
}