이번에 풀어본것은 백준 4673번 의 함수 2단계 문제이다.
문제
셀프 넘버는 1949년 인도 수학자 D.R. Kaprekar가 이름 붙였다. 양의 정수 n에 대해서 d(n)을 n과 n의 각 자리수를 더하는 함수라고 정의하자. 예를 들어, d(75) = 75+7+5 = 87이다.
양의 정수 n이 주어졌을 때, 이 수를 시작해서 n, d(n), d(d(n)), d(d(d(n))), ...과 같은 무한 수열을 만들 수 있다.
예를 들어, 33으로 시작한다면 다음 수는 33 + 3 + 3 = 39이고, 그 다음 수는 39 + 3 + 9 = 51, 다음 수는 51 + 5 + 1 = 57이다. 이런식으로 다음과 같은 수열을 만들 수 있다.
33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ...
n을 d(n)의 생성자라고 한다. 위의 수열에서 33은 39의 생성자이고, 39는 51의 생성자, 51은 57의 생성자이다. 생성자가 한 개보다 많은 경우도 있다. 예를 들어, 101은 생성자가 2개(91과 100) 있다.
생성자가 없는 숫자를 셀프 넘버라고 한다. 100보다 작은 셀프 넘버는 총 13개가 있다. 1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 97
10000보다 작거나 같은 셀프 넘버를 한 줄에 하나씩 출력하는 프로그램을 작성하시오.
각 숫자가 자릿수를 가지는 부분에 한자릿수를 계속해서 더하는 수열 함수이다. 수열 함수는 많은 수를 여러번 더하거나 규칙적인 수의 합을 찾는다면 함수로써 처리하기 좋기 때문에 이러한 문제가 있다고 본다.
풀이 코드는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#include <iostream>
using namespace std;
int arr[10000] = { 1, };
void self_number() {
int temp = 0;
for (int i = 1; i < 10000; i++) {
if (i < 10) {
arr[i + i] = 1;
continue;
}
else if (i < 100) {
arr[i + i / 10 + i % 10] = 1;
continue;
}
else if (i < 1000) {
arr[i + i / 100 + i % 100 / 10 + i % 10] = 1;
continue;
}
else if (i < 10000) {
temp = i + i / 1000 + i % 1000 / 100 + i % 100 / 10 + i % 10;
if (temp < 10000) {
arr[temp] = 1;
continue;
}
}
}
}
int main() {
self_number();
for (int i = 1; i < 10000; i++) {
if (!arr[i]) {
cout << i << endl;
}
}
return 0;
}
|
cs |
각 숫자별로 자릿수를 숫자의 크기를 비교하고 자릿수에 맞는 숫자대로 합을 더해나가는 것이다. 함수를 안써도 되지만 나름 깔끔해지니 이번 문제에 들어가 있는것 같다. 그리고 자릿수는 이미 문제에서(10,000보다 작거나 같은 셀프 넘버를 한 줄에 하나씩 증가하는 순서로 출력한다.) 제시해주었기에 if문들도 제작이 가능한것이다. 추후 더큰 숫자를 다루는 문제도 있다면 이에 대해서도 다뤄보고자 한다.
*알아두면 좋은 문법
continue
continue 문은 현재 루프 몸체의 끝으로 이동하는 편리한 방법을 제공한다. 현재 반복을 일찍 종료하고자 할 때 유용하다.
쉽게 말해서 coninute 문을 사용하여 일부 코드를 실행하지 않고 점프할 수 있다.
4673번: 셀프 넘버
셀프 넘버는 1949년 인도 수학자 D.R. Kaprekar가 이름 붙였다. 양의 정수 n에 대해서 d(n)을 n과 n의 각 자리수를 더하는 함수라고 정의하자. 예를 들어, d(75) = 75+7+5 = 87이다. 양의 정수 n이 주어졌을 때,
www.acmicpc.net