🔗https://www.acmicpc.net/problem/4673
❓
처음엔 문제를 이해하는 것도 어려웠다.
셀프 넘버가 뭔진 대충 알겠는데, 이 수가 셀프 넘버인지 아닌지 대체 어떻게 알지?
식을 내가 새롭게 세워야 하나? 하지만 테스트 땐 검색을 못할텐데... 별의 별 생각을 다했다.
❗
다시 생각해보니 그 수가 셀프넘버인지 아닌지 아는 건 필요 없었다.
필요했으면 그 방법을 문제에서 먼저 제시했겠지...
문제에서 주어진 정보 외의 것을 사용하려고 하는 버릇을 버려야겠다는 생각이 들었다.
✨ 참고
https://velog.io/@yu-jin-song/BOJ-4673-%EC%85%80%ED%94%84-%EB%84%98%EB%B2%84
더보기
풀이1
- 셀프넘버가 아닌 숫자들을 담을 HashSet 선언
- 함수 d 작성
- 1부터 10000까지의 정수 n에 대한 d(n) 값을 HashSet에 저장
- 다시 for문을 통해 1부터 10000까지 돌며 각 숫자가 HashSet에 들어있는지 확인
- 들어있지 않다면 해당 숫자는 셀프넘버
코드
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashSet;
//import java.util.stream.Stream;
public class SelfNumber4673 {
public static void main(String[] args) throws IOException {
SelfNumber4673 sn = new SelfNumber4673(); // 클래스 내 메소드 호출 위함
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
HashSet<Integer> notSelfNumber = new HashSet<Integer>();
for (int n=1; n<=10000; n++) {
notSelfNumber.add(sn.d(n));
}
for (int n=1; n<=10000; n++) {
if (!notSelfNumber.contains(n))
bw.write(n + "\n");
}
bw.close();
}
int d(int n) {
int newNum = n;
// 1. 문자열로 변환해서 구하기
String strN = Integer.toString(n);
for (int i=0; i<strN.length(); i++) {
newNum += strN.charAt(i) - '0';
}
// 2. Stream 이용해 구하기 - 시간 더 오래 걸림
// for (int i : Stream.of(String.valueOf(n).split("")).mapToInt(Integer::parseInt).toArray()) {
// newNum += i;
// }
return newNum;
}
}
풀이2
정수가 들어가는 HashSet 대신 boolean 값이 들어가는 배열을 이용하는 방법도 있다.
수행 시간을 확인해보니 훨씬 시간이 덜 걸리는 것을 알 수 있었다.
방법은 동일하다.
- 배열의 크기는 넉넉잡아 100001로 설정
- 배열의 d(n) 위치 값을 true로 설정
- false 값을 가지는 인덱스 출력
코드
// HashSet<Integer> notSelfNumber = new HashSet<Integer>();
boolean[] notSelfNumber = new boolean[100001];
for (int n=1; n<=10000; n++) {
// notSelfNumber.add(sn.d(n));
notSelfNumber[sn.d(n)] = true;
}
for (int n=1; n<=10000; n++) {
// if (!notSelfNumber.contains(n))
if (!notSelfNumber[n])
bw.write(n + "\n");
}
bw.close();
주석 처리한 부분은 기존 코드 내용이다.
밑줄의 내용으로 바꾸면 된다.
풀이 3 (+ 23.08.09)
셀프 넘버는 10,000보다 작으므로 d(n) 함수 내에서 다른 함수 호출 없이 각 자리별 수를 바로 구했다.
- 크기 10,000인 boolean 배열 생성
- 배열 크기만큼 for문 돌면서 d(n) 함수 실행
- 결과가 10,000보다 크면 continue
- 작으면 배열의 해당 인덱스 값을 true로 설정
- 배열 내 요소가 false면 해당 요소의 인덱스 값 출력
코드
public class Main {
static int d(int n) {
int n4 = n / 1000;
int n3 = n % 1000 / 100;
int n2 = n % 100 / 10;
int n1 = n % 10;
return n + n1 + n2 + n3 + n4;
}
public static void main(String[] args) {
boolean numArr[] = new boolean[10000];
for (int i=1; i<10000; i++) {
int num = d(i);
if (num >= 10000) continue;
numArr[num] = true;
}
for (int i=1; i<10000; i++) {
if (numArr[i] == false)
System.out.println(i);
}
}
}
'코딩테스트 > 백준' 카테고리의 다른 글
[백준 2751] 수 정렬하기 2 - Java (0) | 2022.12.04 |
---|---|
[백준 2869] 달팽이는 올라가고 싶다 - Java (0) | 2022.11.14 |
[백준 2563] 색종이 -Java (1) | 2022.10.28 |
[백준 2941] 크로아티아 알파벳 - Java (+23.09.05) (0) | 2022.10.21 |
[백준 5622] 다이얼 - Java (0) | 2022.10.19 |
댓글