문제
음이 아닌 정수 X의 자릿수가 가장 큰 자릿수부터 작은 자릿수까지 감소한다면, 그 수를 감소하는 수라고 한다. 예를 들어, 321과 950은 감소하는 수지만, 322와 958은 아니다. N번째 감소하는 수를 출력하는 프로그램을 작성하시오. 0은 0번째 감소하는 수이고, 1은 1번째 감소하는 수이다. 만약 N번째 감소하는 수가 없다면 -1을 출력한다.
풀이
10 이하의 수는 수와 동일한 N번째 값을 가진다.
10 초과의 수는 감소하는 수 전체 리스트를 구한 뒤 N번째 수를 출력하는 방식을 사용하였다.
감소하는 수를 구하는 방식은 재귀를 이용하여 구하였다.
for(int i = 0 ; i < 10 ; i++) {
if(num % 10 > i) {
calculator((num * 10) + (long)i);
}
}
위의 코드처럼 가장 마지막 수가 현재 수보다 크다면 재귀로 다음 값을 구하면 된다.
이렇게 값을 구하면
0
1, 10
2, 21, 20, 210
3, 32, 321, 320, 31, 310, 30
4...
순으로 값이 나오게 되는데 list를 정렬하면 N번째 수를 구할 수 있다.
감소하는 수의 최대수는 9876543210 이므로 해당 수보다 크면 끝내게 하였다.
if(num > Long.parseLong("9876543210")) {
return;
}
또는 9876543210 이 10자리 수 이므로 10자리수가 넘어가는 상황이면 끝내게 할 수 있다.
if(ndigit > 10) {
return;
}
위와 같은 경우에는 아래와 같이 현재 자리수 개수를 넣어주는 방식으로 재귀 메서드를 구성해야한다.
for(int i = 0 ; i < 10 ; i++) {
if(num % 10 > i) {
calculator((num * 10) + (long)i, ndigit + 1);
}
}
<최대 크기를 이용한 방법 전체코드>
import java.io.*;
import java.util.*;
public class Main {
static StringBuilder sb = new StringBuilder();
static List<Long> list = new ArrayList<>();
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
if(n <= 10) {
System.out.println(n);
}
else {
for(int i = 0 ; i < 10 ; i++) {
calculator((long)i);
}
Collections.sort(list);
if(list.size() <= n) {
System.out.println(-1);
}
else {
System.out.println(list.get(n));
}
}
}
public static void calculator(long num) {
if(num > Long.parseLong("9876543210")) {
return;
}
list.add(num);
for(int i = 0 ; i < 10 ; i++) {
if(num % 10 > i) {
calculator((num * 10) + (long)i);
}
}
}
}
<자릿수를 이용한 방법 전체코드>
import java.io.*;
import java.util.*;
public class Main {
static StringBuilder sb = new StringBuilder();
static List<Long> list = new ArrayList<>();
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
if(n <= 10) {
System.out.println(n);
}
else {
for(int i = 0 ; i < 10 ; i++) {
calculator((long)i, 1);
}
Collections.sort(list);
if(list.size() <= n) {
System.out.println(-1);
}
else {
System.out.println(list.get(n));
}
}
}
public static void calculator(long num, int ndigit) {
if(ndigit > 10) {
return;
}
list.add(num);
for(int i = 0 ; i < 10 ; i++) {
if(num % 10 > i) {
calculator((num * 10) + (long)i, ndigit + 1);
}
}
}
}
'알고리즘 공부 > 구현 , 시뮬레이션' 카테고리의 다른 글
[백준] 10830 행렬 제곱 <Java> (0) | 2021.12.13 |
---|---|
[백준] 14890 경사로 (0) | 2021.10.23 |
[백준] 14500 테트로미노 (0) | 2021.10.22 |
[백준] 15684 사다리 조작 (0) | 2021.10.21 |
[백준] 17144 미세먼지 안녕! (0) | 2021.10.21 |