[Java] 백준 4673번

Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1 3 5 7 9 20 31 42 53 64 | | <-- a lot more numbers | 9903 9914 9925 9927 9938 9949 9960 9971 9982 9993
접근 방식
핵심은 셀프넘버인 수를 구하는 것이 아니라 셀프넘버가 아닌 수를 구하는 것이다.
먼저 셀프넘버를 구하는 함수(notSelfNum)를 작성하였다.
- 셀프넘버 = 본인 + 본인의 N자리별 수
본인의 N자리별 수를 알아내려면 숫자(a)를 10으로 반복해서 나눠가면서, 10으로 나머지 연산을 하면 일의 자리를 얻어낼 수 있다.
1
2
3
4
5
6
7
8
public static int notSelfNum(int a) {
int self = a;
while(a != 0) {
self = self + (a % 10);
a /= 10;
}
return self;
}
셀프넘버를 구했으니 셀프넘버가 아닌 수를 어떻게 찾아야 할까?
1부터 10000까지 수 중 셀프넘버인 수를 제거하는 방식으로 작성하였다.
- 1-10000까지 모든 수가 존재하는 배열(A)과 1-10000까지의 셀프넘버 배열(B)을 만든다.
- A에서 B의 원소를 제거한다.
1
2
3
4
5
6
7
8
9
10
ArrayList<Integer> result = new ArrayList<>(); // A
ArrayList<Integer> self_nums = new ArrayList<>(); // B
for (int i=0; i<=n; i++) {
result.add(i); // 1-10000까지 모든 수 배열
self_nums.add(Main.notSelfNum(i)); // // 1-10000까지 셀프넘버 배열
}
for (int j=0; j<=n; j++) { // A배열에서 셀프넘버 숫자만 제거
result.remove(self_nums.get(j));
}
작성코드
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
import java.util.*;
class Main {
public static void main(String[] args) {
int n = 10000;
selfNum(n);
}
public static void selfNum(int n) {
ArrayList<Integer> result = new ArrayList<>();
ArrayList<Integer> self_nums = new ArrayList<>();
for (int i=0; i<=n; i++) {
result.add(i);
self_nums.add(Main.notSelfNum(i));
}
for (int j=0; j<=n; j++) {
result.remove(self_nums.get(j));
}
for (int a : result) System.out.println(a);
}
public static int notSelfNum(int a) {
int self = a;
while(a != 0) {
self = self + (a % 10);
a /= 10;
}
return self;
}
}
회고
- 셀프넘버를 구하는 로직을 별도로 함수를 작성하여 핵심 비즈니스 로직을 분리함으로 깔끔한 코드를 작성할 수 있다는 것을 알게되었다.
- 효율적인 알고리즘 패턴을 우선적으로 찾지 않고 코딩부터 시작하였는데, 더 효율적인 패턴을 찾게되면 로직을 변경해야 하는 경우가 생겨 불필요한 시간을 소모하였다.