Algorithm

[JAVA] 백준 문제 1065 - 한수

isaac.kim 2022. 4. 28.
728x90
반응형

[JAVA] 백준 문제 1065 - 한수

 

백준 문제 1065 - 한수

JAVA로 문제를 풀어보자.

 



오늘은 백준 사이트에서 '문제-단계별 문제풀기' 카테고리의 1065번 문제를 풀기로 한다.

백준 사이트의 1065번 문제는 다음과 같다.

출처 : 백준 홈페이지

문제

어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오.

 

입력

첫째 줄에 1,000보다 작거나 같은 자연수 N이 주어진다.

 

출력

첫째 줄에 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력한다.

 

 

예제 입력과 출력

입력1

110

출력1

99

입력2

1

출력2

1

입력3

210

출력3

105

입력4

1000

출력4

144

입력5

500

출력5

119

 

 


문제 풀이

 

제가 푼 알고리즘이 정답이 아닐 수 있습니다.

 

먼저 1부터 입력된 숫자까지 한수를 찾아내는 문제이다.

 

가장 먼저 입력을 받는다. 

Scanner sc = new Scanner(System.in);
int n = sc.nextInt();

Scanner 클래스를 사용해서 입력받는다. 

Java에서 입력받는 클래스는 BufferedReader도 존재하는데 속도가 더 빠르다. 하지만 코드가 조금이라도 간결해보이는게 좋아서 Scanner 클래스를 사용했다.

 

항상 Java로 문제를 풀면 드는 생각이지만, 다른 언어에 비해 코드가 길게 뽑히는 것 같다.

(간결한 다른 코드가 좋아보이긴 함.)

 

그리고 1부터 입력받은 n까지 '한수'의 개수를 구하는 반복문과 함수를 작성했다.

int count = 0;
// 한수 구하기
for ( int i  = 1 ; i  <= n; i ++ )
	if ( getHansuCount(i) ) count ++;

1부터 n까지 반복되는 과정에서 한수를 찾게되면 count의 값을 1씩 증가 시키는 코드를 작성한 것이다.

 

다음은 한수인지 아닌지를 확인하는 메서드이다. 함수파트여서 getHansuCount 메서드로 작성했다.

public static boolean getHansuCount(int n) {
    int num = n;
    int length = Integer.toString(n).length();
    int[] nums = new int[length]; 
    int[] subs = new int[length - 1];
    int temp = 0;
    . . . .
}

num은 1~n 까지의 정수가 들어오고, num이 한수인지를 확인해야 한다. 우선 n이 한 자리 수 이거나, 두 자리 수 이면 한수이다. 등차 수열인지 비교할 대상이 없다. 그냥 등차 수열이라고 할 수 있다.

 

세 자리 수 부터는 예를 들어 123이 [ 1 -> 2 차이 1 ], [ 2 -> 3 차이 1 ] 로 차이가 일정하기 때문에 등차 수열임을 비교하고 확인할 수 있다. 124는 아니다. [ 1 -> 2 차이 1 ], [ 2 -> 4 차이 2 ] 로 차이가 일정하지 않아 등차 수열로 볼 수 없다.

 

메서드의 리턴 값은 boolean 값이다. n이 한수이면 true를 반환하고, 한수가 아니면 false를 반환하게 된다.

public static boolean getHansuCount(int n) {
    int num = n;
    int length = Integer.toString(n).length();
    int[] nums = new int[length]; 
    int[] subs = new int[length - 1];
    int temp = 0;
    boolean check = true;
    // 100 이하는 모두 한 수
    if (n < 100) return check;
    else {
     for ( int i = 0; i < length; i++) {
        nums[i] = num % 10;
        num = num / 10;
     }
     // 차이 비교
     for (int i = 0; i < length - 1 ; i++) {
        subs[i] = nums[i+1] - nums[i];
        temp = subs[i];
     }
     for (int i = 0; i < length - 1 ; i++)
        if (temp != subs[i]) check = false;
    }
    return check;
}

100보다 작은 수는 한수이므로 바로 return한다. 100이상의 정수부터는 각 자리의 숫자를 따오고, 각 자리 수의 차이를 저장한다. 각 자리 수의 차이가 모두 같다면 등차 수열이므로 true를 반환하게 된다. 사실 불필요한 코드들이 있다. 줄이면 충분히 줄일 수 있지만 처음 작성한 그대로 코드를 두기로 한다. (귀차니즘...)

 

 

전체 소스코드

import java.util.Scanner;

public class Main {
   public static void main(String[] args) {
      Scanner sc = new Scanner(System.in);
      int n = sc.nextInt();
      int count = 0;
      // 한수 구하기
      for ( int i  = 1 ; i  <= n; i ++ )
         if ( getHansuCount(i) ) count ++; 
      
      System.out.println(count);
      sc.close();
   }
   
   public static boolean getHansuCount(int n) {
      int num = n;
      int length = Integer.toString(n).length();
      int[] nums = new int[length]; 
      int[] subs = new int[length - 1];
      int temp = 0;
      boolean check = true;
      // 100 이하는 모두 한 수
      if (n < 100) return check;
      else {
         for ( int i = 0; i < length; i++) {
            nums[i] = num % 10;
            num = num / 10;
         }
         // 차이 비교
         for (int i = 0; i < length - 1 ; i++) {
            subs[i] = nums[i+1] - nums[i];
            temp = subs[i];
         }
         for (int i = 0; i < length - 1 ; i++)
            if (temp != subs[i]) check = false;
   
      }
      return check;
   }
}

 

채점 결과

 


틀린 내용이 있다면 댓글 달아주세요! 도움이 되셨다면 광고 꾹! 제게 큰 힘이 됩니다. 감사합니다.^^

728x90
반응형