티스토리 뷰

728x90
반응형

백준 온라인 저지(BOJ) 4673번 셀프 넘버

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

 

4673번: 셀프 넘버

셀프 넘버는 1949년 인도 수학자 D.R. Kaprekar가 이름 붙였다. 양의 정수 n에 대해서 d(n)을 n과 n의 각 자리수를 더하는 함수라고 정의하자. 예를 들어, d(75) = 75+7+5 = 87이다. 양의 정수 n이 주어졌을 때,

www.acmicpc.net

* 사용언어 : C언어, C++

 

1. 문제

양의 정수 n 에 대해서 d(n) 은 n 과 n 의 각 자리수를 더하는 함수

n 을 d(n) 의 생성자라고 하는데, 생성자가 없는 숫자를 셀프 넘버라고 할 때,

10,000 보다 작거나 같은 셀프 넘버를 한 줄에 하나씩 출력

 

2. 풀이

함수 카테고리에 속하는 문제라서 일단 d(n) 을 함수로 구현하고 시작했습니다.

입력받은 숫자(n)에 1의 자리(n % 10)를 더해주고 n 을 10 으로 나눈 뒤,

n 이 0이 될 때까지 반복하는 방식으로 구현했습니다.

 

하지만 문제는 d(n) 이 아닌 d(n) 이 없는 n 을 출력하는 문제입니다.

그래서 d(n) 에서 n 을 어떻게 찾아서 출력할까를 오랜 시간 고민했는데 결론이 나지 않았습니다.

 

그러다가 문득 n 을 1부터 10,000까지 반복하면서 d(n) 을 만들고,

d(n) 이 한 번도 생성되지 않으면 셀프 넘버로 출력하자는 결론을 냈습니다.

 

예를 들어, n 이 24 라면 d(n) 은 24 + 4 + 2 = 30 이 됩니다.

30은 생성자가 있는 숫자이므로 미리 생성해둔 배열의 30번째 자리에 체크를 해둡니다.

(셀프 넘버가 아니라는 뜻으로 1 로 설정)

 

n 이 d(n) 보다 클 수 없기 때문에

n 을 1부터 10000까지만 반복하면 d(n) = 10000 까지 모두 확인한 셈이 됩니다.

 

확인이 완료된 후에는 한 번도 체크가 안 된,

즉 배열의 값이 0 인 자리의 index 를 출력합니다.

 

3. 코드

#include <stdio.h>

const int LM = 10000;
int a[LM];

int d(int n) {
	int ret = n;
	while (n) {
		ret += n % 10;
		n /= 10;
	}
	return ret;
}

int main() {
	for (int i = 0; i < LM; ++i) {
		int ret = d(i);
		if (ret < LM) a[ret] = 1;
	}

	for (int i = 0; i < LM; ++i) {
		if (!a[i]) printf("%d\n", i);
	}
	return 0;
}

 

728x90
반응형
댓글