[BOJ] 1065 한수 (JAVA)

joyful·2021년 4월 9일
0

Algorithm

목록 보기
40/65
post-custom-banner

✅ 문제

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

✅ 입력

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

✅ 출력

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

✅ 예제 1

▼ 입력

110

▼ 출력

99

✅ 예제 2

▼ 입력

1

▼ 출력

1

✅ 예제 3

▼ 입력

210

▼ 출력

105

✅ 예제 4

▼ 입력

1000

▼ 출력

144

풀이

등차수열의 정의를 다시 보자.

등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다.

예를 들자면, 1, 3, 5, 7, 9, ... 는 등차수열이라고 할 수 있다.

왜 일까? 맨 앞의 숫자 1을 첫째 항이라고 하고, 그 다음 숫자 3을 둘째 항이라고 했을 때, 두 항의 차이는 이 수열의 모든 연속하는 두 항들(13, 35, 57, ...)의 차이와 일정하기 때문이다. (이 때 두 항의 차이는 통적으로 나타나는 이이므로, 공차라고 한다.)


그렇다면 한수는?

어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다.

예를 들어, 246의 각 자리를 분리하면 2, 4, 6이 된다. 이 숫자들을 수열로 본다면, 연속된 두 개의 수(항)의 차이는 '2'로 일정하기 때문에 등차수열을 이룬다고 할 수 있다. 즉, 246은 한수이다.

반면에 212를 분리하면 각 자리수는 2, 1, 2 로, 연속된 두 개의 수의 차이는 일정하지 않기 때문에 등차수열을 이룬다고 할 수 없다. 즉, 212는 한수가 아니다.

기본적인 개념을 정리했으니 이제 코드 짜는 방식을 생각해보자.

🔎 메인 메소드

  • for문을 입력받은 값만큼 반복하고, 등차수열을 판별하는 메소드에 매개변수를 전달하여 등차수열인지 아닌지 판별한다.
  • 한수의 갯수를 세는 변수를 선언하고, 등차수열임이 판별되면 갯수를 증가시킨다.

🔎 등차수열 판별 메소드

등차수열인지 아닌지 판별 여부가 필요하므로 리턴 타입은 boolean 타입으로 지정한다.

  • 전달되어온 값의 각 자리를 추출한다.
  • 1부터 99까지는 등차수열이므로 바로 true를 리턴한다.
  • 첫째 항과 둘째 항을 구하고, 변수 하나를 선언하여 공차를 저장한다.
  • 셋째 항부터 마지막 항까지 for문을 통해 반복하며 현재 항의 값을 추출하고, 앞 항과의 차이를 구하여 공차와 비교한다.
  • 공차와 앞 항과의 차이가 같지 않다면 등차수열이 아니므로 false를 리턴하고, 같다면 현재 값을 앞 항으로 지정한다.
  • for문을 빠져나왔다면 등차수열이므로 true를 리턴한다.

💻 코드

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		scanner.close();
		
		int cnt = 0;
		
		for(int i=1; i<=n; i++) {
			if(getNum(i))	// 등차수열(전달되어온 값이 true)일 경우
				cnt++;	// 한수 갯수 증가
		}
		
		System.out.println(cnt);
	}
	
	static boolean getNum(int n) {
		String str = String.valueOf(n);
		
		if(str.length() < 3)	// 1~99까지는 무조건 등차수열
			return true;
		
		int num1 = Character.digit(str.charAt(0), 10);	// 첫째 항
		int num2 = Character.digit(str.charAt(1), 10);	// 둘째 항
		int bal = num2 - num1;	// 공차
		
		for(int i=2; i<str.length(); i++) {
			int temp = Character.digit(str.charAt(i), 10);
			if(temp-num2 != bal)  // 등차수열 아닐 경우
				return false;
			else	// 등차수열이라면
				num2 = temp;	// 현재 값을 앞 항으로 지정
		}
		
		return true;	// for문을 무사히 빠져나왔다면 등차수열이므로
		
	}
}
profile
기쁘게 코딩하고 싶은 백엔드 개발자
post-custom-banner

0개의 댓글