문제 바로가기 : https://www.acmicpc.net/problem/1174
코드
비트마스크 이용
메모리 : 14572KB
시간 : 148ms
언어 : Java 11
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
static int N;
static int[] arr = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
static List<Long> ans;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
ans = new ArrayList<>();
for (int i = 0; i < (1 << 10); i++) {
long num = 0;
for (int j = 0; j < 10; j++) {
if ((i & (1 << j)) != 0) {
num = num * 10 + arr[j];
if (!ans.contains(num)) {
ans.add(num);
}
}
}
}
Collections.sort(ans);
if (ans.size() < N) {
System.out.println(-1);
} else {
System.out.println(ans.get(N - 1));
}
}
}
코드
dfs조합을 이용
메모리 : 14608KB
시간 : 156ms
언어 : Java 11
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
static int N;
static int[] arr = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
static List<Long> ans;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
ans = new ArrayList<>();
dfs(0, 0);
Collections.sort(ans);
if (N > ans.size()) {
System.out.println(-1);
} else {
System.out.println(ans.get(N - 1));
}
}
private static void dfs(long num, int idx) {
if (!ans.contains(num)) {
ans.add(num);
}
if (idx >= 10) {
return;
}
dfs((num * 10) + arr[idx], idx + 1);
dfs(num, idx + 1);
}
}
풀이
일단 공통적인 풀이는 다음과 같다.
- 왼쪽부터 자리수가 감소하는 가장 큰 수는 9876543210 이다. 따라서 9876543210 보다 작은 수들 중 왼쪽부터 오름차순인 수를 찾아야 한다.
- 조합을 만드는데, 숫자의 배열 arr가 가장 큰 수의 배열과 같다. 조합을 만들 때 idx는 왼쪽(0)에서 오른쪽 (N)으로 이동하기때문이다. idx를 선택하거나 선택하지않고 넘어가면서 계속 뒤에 작은 수들을 붙일 수 있기 때문이다. 만들어진 조합의 앞자리 수는 항상 뒷자리 수보다 크다는 것을 보장받는다.
비트마스크 : 10가지의 숫자 중 어떤 숫자를 선택할 것인지==해당 자리수의 비트가 1인지 여부이다.
//모든 경우의 수 : 2의 10제곱
for (int i = 0; i < (1 << 10); i++) {
long num = 0;
//숫자 10가지 중에 무엇이 선택됐는지 볼것이다
for (int j = 0; j < 10; j++) {
//i와 2의 j제곱이 0이 아니면 == 해당 자리수가 1이면
//해당 idx는 선택받았다!
if ((i & (1 << j)) != 0) {
//10을 곱해 자릿수를 밀어주고, 해당 idx 더하기
num = num * 10 + arr[j];
//중복방지
if (!ans.contains(num)) {
ans.add(num);
}
}
}
}
dfs : 평범한 조합..
'Algorithm' 카테고리의 다른 글
[Algo] 백준 24913 개표 JAVA (0) | 2024.05.08 |
---|---|
[Algo] 백준 28071 승형이의 사탕 사기 JAVA (0) | 2024.05.08 |
[Algo] 백준 17827 달팽이 리스트 JAVA (0) | 2024.05.08 |
[Algo] 백준 25421 조건에 맞는 정수의 개수 JAVA (1) | 2024.05.08 |
[Algo] 백준 19699 소-난다JAVA (0) | 2024.05.08 |