ALGORITHM/PROGRAMMERS

[프로그래머스] 줄 서는 방법 (연습문제)

0298 2020. 12. 12. 16:37

programmers.co.kr/learn/courses/30/lessons/12936?language=java

 

코딩테스트 연습 - 줄 서는 방법

n명의 사람이 일렬로 줄을 서고 있습니다. n명의 사람들에게는 각각 1번부터 n번까지 번호가 매겨져 있습니다. n명이 사람을 줄을 서는 방법은 여러가지 방법이 있습니다. 예를 들어서 3명의 사람

programmers.co.kr

2020-12-12


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
import java.util.ArrayList;
import java.util.Arrays;
 
public class Solution12936 {
    public static int n;
    public static long k; // test용
    public static ArrayList<Integer> list;
    public static long fact[], fa;
 
    public static void init(int num) { // factorial 계산
        fact[1= 1;
        fact[2= 2;
        
        for(int i = 3; i <= num; i++) {
            fact[i] = i * fact[i-1];
        }
    }
 
    public static void main(String[] args) {
        n = 4;
        k = 10;
        int answer[] = new int[n];
        fact = new long[n+1];
        list = new ArrayList<>();
        for(int i = 1; i <= n; i++) list.add(i);
        init(n);
        
        long start = k-1//k가 한 블럭의 마지막일 경우 다른 블럭으로 잡힘 
        for(int i = 1; i < n; i++) {
            int idx = (int) (start / fact[n-i]); 
                answer[i-1= list.get(idx);
                list.remove(idx);
                start %= (fact[n-i]);
        }
        
        answer[n-1= list.get(0);
        System.out.println(Arrays.toString(answer)); // test용
    }
}
cs

 

#문제풀이

n == 4이고 k == 10 이라고 가정해본다. 줄 설 수 있는 숫자들을 나열해보면 다음과 같다. 그리고 규칙을 발견할 수가 있다. 첫째자리 기준으로 크게 두 블럭으로 나눌 수 있다. 또, 하나의 블럭(6개)을 쪼개보면, 2개씩, 1개씩, 1개씩 나눌 수 있다. 마지막을 제외하고 6, 2, 1 숫자를 보면 각각 3!, 2!, 1!을 의미함을 알 수 있다. 

1234
1243
1324
1342
1423
1432 

-------
2134
2143

2314

2341 ---> k == 10

2413
2431 

 

그 다음 각 자리가 갖을 수 있는 index 값을 찾아야하는데, 처음에는 k를 시작점으로 잡고 했었다. 하지만 k가 6일때, k/6을 하면 1이 나오고, 그러면 저 규칙대로 정답을 만들 수 없었다. 그래서 처음 기준점을 k-1로 잡았고, (k-1) / factorial[n-1] 나눈 값을 index로 생각하였다. 그렇게 하면 파란색 부분 한 블럭의 첫 번째 숫자를 구할 수 있다. 이것을 n-1만큼 반복했고 맨 마지막에 list에 남은 값은 answer의 맨 마지막 값으로 넣었다.

 

n == 4, k == 10일때

list start fact[n-i] answer (index)
1, 2, 3, 4 9 (k-1) 6 (3!) 2 (1)
1, 3, 4 3 (9 %= 3) 2 (2!) 3 (1)
1, 4 1 (3 %= 2)  1 (1!) 4 (1)

그리고 마지막으로 남은 1을 넣어주면 [2, 3, 4, 1] 을 출력할 수 있다.