본문 바로가기

알고리즘/백준

[백준 알고리즘 자바]1065 : 한수

수행일자 : 2021.08.10


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

 

1065번: 한수

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

www.acmicpc.net


문제

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

입력

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

출력

  • 10,000보다 작거나 같은 셀프 넘버를 한 줄에 하나씩 증가하는 순서로 출력한다.

입출력 예제


BufferedReader를 사용해서 풀어보았다.

 

문제 이해를 먼저 해보자.

등차수열이란 연속된 두 수 사이의 차이가 일정한 것을 말한다.

예를 들어, 135 라는 숫자를 보면 1과 3의 차이가 2이고 3과 5의 차이가 2이므로 135라는 수는 두 수의 차이 즉, 공차가 2인 숫자라고 할 수 있다.

여기에서 헷갈릴 수 있는 점은 아래와 같이 두 가지가 있다.

  • 첫째, 두 자리로 이루어진 수들은 모두 등차수열이다.
  • 둘째, 공차가 양수일수도 있고 음수일수도 있다.

먼저 두 자리로 이루어진 수들이 모두 등차수열인 이유에 대해 알아보자.

등차수열이란 연속된 두 수 사이의 차이가 일정한 것이라고 했다. 예를 들어 25라는 숫자를 보자. 이 숫자는 공차가 3인 등차수열이라고 할 수 있다. 이게 무슨 말이냐 하면, 두 자리수의 숫자들은 모두 1개의 공차를 갖고 있는데 이를 등차수열로 본다는 것이다. 한 자리수도 마찬가지이다. 1은 공차가 0인 등차수열로 보는 것이다.

즉, 1부터 99까지는 무조건 등차수열이라고 본다는 것이다. 두 수 사이에 차이가 발생했기 때문이다.

 

이제 세 자리수로 넘어가보자. 예제에 나온대로 210을 보자. 210이라는 숫자는 공차가 1 즉, 각 숫자마다 1씩 차이가 나기에 등차수열이 맞다. 

그러면 101을 보자. 101은 각 수의 차이가 -1, +1 로 서로 다른 공차가 발생한다. 그러므로 101은 등차수열이 아니다.

 

이러한 부분들을 참고하여 코드를 작성해보자.

선언할 변수는 다음과 같다.

  • 입력받을 변수 N
  • 등차수열인 수의 개수를 저장할 변수 cnt
  • 숫자의 각 자릿수를 저장할 변수 A (백의자리) / B (십의자리) / C (일의자리)

먼저 등차수열의 여부를 확인하여 갯수를 누적해주는 함수를 작성해보자.

필자는 해당 함수의 이름을 NumberCount라 정했다.

이 함수 안에 일단 등차수열의 개수를 저장할 변수 cnt 를 선언한다.

그리고 100보다 작은 즉 1~99까지의 수는 모두 등차수열이기 때문에 입력받은 수 자체가 등차수열의 개수가 되는 것이므로 입력받은 수인 [ N ] 을 그대로 출력해준다.

  • 예를 들어, 67을 입력받았다고 하면 1부터 67까지의 수가 모두 등차수열인 것이므로 총 등차수열의 개수는 67이 되기 때문이다.

이제 세 자리수의 수들 중에 등차수열을 찾아내는 코드를 작성해보자.

먼저, 일단 100 이상의 수라고 하면 그 이전까지는 모두 등차수열이 성립되므로 [ cnt ] 가 99부터 시작해야 한다.

그리고 100부터 입력받은 수까지 도는 for 문을 작성한다.

이 안에서 입력받은 수 각각을 자리마다 하나씩 쪼개서 저장한다.

예를 들어 502 가 입력되었다고 했을 때, 각 A / B / C 의 변수는 다음과 같은 값이 저장된다.

  • A 는 i / 100 이므로 5가 저장된다.
  • B 는 ( i / 10 ) % 10 이므로 0이 저장된다.
  • C 는 i % 10 이므로 2가 저장된다.

여기에서 등차수열임을 확인하여 [ cnt ] 를 누적해야 하므로 B-A 와 C - B 가 동일한 경우에 [ cnt ] 를 누적한다는 if문을 추가해주면 된다.

함수이므로 return 값이 무조건 필요하다. 함수가 끝나기 전에 return cnt; 를 통해 누적된 cnt 의 값을 출력한다.

 

이제 메인 메소드에서 작성한 함수인 NumberCount 만 호출해주면 된다.

답안 소스

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int N = Integer.parseInt(br.readLine());
		
		System.out.println(NumberCount(N));
	}

	private static int NumberCount(int N) {
		
		int cnt = 0;
		
		if(N<100) {
			return N;
		} else {
			cnt = 99;
			
			for(int i=100; i<=N; i++) {
				
				int A = i / 100;
				int B = (i / 10) % 10;
				int C = i % 10;
				
				if(B-A == C-B) {
					cnt++;
				}
			}
		}
		return cnt;
	}
}