BOJ 문제번호 1065

  우선 주어지는 자연수 N의 범위는 1보다 크거나 같고, 1000보다 작거나 같은 자연수 이다. 예를 들어 123이 주어졌을 때, 각 자리수가 1씩 증가하기 때문에 등차수열로 볼 수 있다. 이와 동일한 조건을 만족하는 숫자들을 카운팅하여 지정된 범위 내에 등차수열 조건을 만족하는 수가 몇개인지 알아보는 것이다.  

  첫번째로, 한자리 숫자와 두자리 숫자의 자연수의 경우 무조건 등차수열이다. 그 이유는 한자리 자연수의 경우 비교를 할 다음 자리 숫자가 없기 때문에, 무조건 등차수열로 본다. 즉, 기본적으로 1~9를 포함하는 범위의 경우 9개는 기본적으로 등차수열을 갖는다. 두자리 자연수의 경우도 마찬가지로 무조건 등차수열이다. 10의 자리 숫자와 1의 자리 숫자의 차이가 공차가 되는데, 그 다음 이어지는 숫자와의 차이를 비교해 볼 수 없기 때문에 등차수열로 본다. 즉 93의 경우 공차가 -6이게 되는데, 다음 비교할 숫자가 없기때문에 등차수열로 보는 것이다. 이렇게 되면 주어진 자연수가 100이상일 경우 1~99는 모두 등차 수열이다. 이제 세자리 수부터 등차수열인지 비교를 해보면 된다. 

  문제를 접근할때, 과거의 공차와 현재의 공차를 비교하기 위해서 2개의 변수를 사용하였다. 그리고 1의자리부터 하나씩 올라가며 각 자리수의 차이를 비교해보고, 각 자리수의 차이가 달라질 경우 비교를 종료하고 다음 숫자를 탐색한다. 여기서 나머지연산과 나눗셈 연산을 사용하였는데, 우선 나머지 연산을 활용하여 제일 끝자리 숫자를 저장하고, 10으로 나누게 되면 자릿수가 한자리씩 밀리게 된다. 이렇게 되면 1의 자리 숫자들을 빼서 인접한 다음 자리 숫자와 차이를 구하기 쉽기 때문이다. 이 과정이 반복될때 10으로 나누는 값이 10보다 작아질 경우 모든 자리수의 차이가 같기때문이므로 정답을 하나 카운트하고 다음 숫자를 또 반복한다. 



% 글을 작성하다 보니, for문을 탐색할때 불필요하게 1부터 99까지 검사를 하는것 같다. for문의 경우 100이 넘을때만 동작하게 하고 그 이전의 자연수는 입력받은 자연수 그대로 출력하면 더 효율적일 것 같다.

#include <iostream>

int main() {
	int N;		// 입력받을 자연수 N
	int answer = 0;							// 등차수열을 만족하는 자연수의 개수
	int temp = 0, n = 0;					// temp: 1의 자리 숫자를 제거하고 남은 수를 임시 저장하는 변수, n: 남아있는 수의 가장 끝자리 숫자
	int diff = 0, before_diff = 0;			// diff: 현재 끝자리 숫자와 인접한 숫자의 차이, before_diff: 이전의 끝자리 숫자와 인접한 숫자의 차이

	scanf_s("%d", &N);

	for (int i = 1; i <= N; i++) {
		if (i < 100) {
			answer++;
		}			// 1~99의 숫자는 모두 등차수열이다
		else {
			temp = i;		
			n = temp % 10;			// 1의 자리 숫자를 저장
			temp = temp / 10;		// 1의 자리를 빼내고 남은 숫자
			diff = (temp % 10) - n;	// 1의 자리 숫자와 그 다음 자리 숫자의 차를 저장
			before_diff = diff;		// 과거 공차로 추정되는 값으로 저장
			while (1) {
				n = temp % 10;
				temp = temp / 10;
				diff = (temp % 10) - n;
				if (before_diff != diff)		// 과거 공차로 추정되는 값과 현재 공차로 추정되는 값을 비교하여 다를 경우 반복문을 나감
					break;
				if (temp < 10) {				// 모든 자리 숫자의 차이가 같을 경우 남은 숫자가 1자리게 되는데 이 경우 해당 숫자는 등차수열이므로 answer을 1개 추가하고 반복문을 나감
					answer++;
					break;
				}
				before_diff = diff;				// 과거 공차로 추정되는 값을 현재 사용된 공차로 업데이트
			}
		}
	}

	printf("%d\n", answer);

}

 

+ Recent posts