PS/Advanced String Manipulation

백준 3080번: 아름다운 이름 (Java)

닻과매 2022. 7. 7. 20:34

https://www.acmicpc.net/problem/3080

 

3080번: 아름다운 이름

상근 선생님은 학생들에게 번호를 붙여주려고 한다. 상근이는 미술 선생님이기 때문에, 이름의 순서도 아름다워야 한다고 생각한다. 따라서, 다음과 같은 규칙을 지켜서 번호를 정하려고 한다.

www.acmicpc.net

 

 

 

 

 

 

 

 


 

풀이

"A, AB, AC, B, C"를 배열하는 경우의 수를 생각해봅시다.

 

이렇게 5개의 이름이 있는 경우, 앞이 "A"로 시작하는 3개의 단어끼리 배열하고, 이후 앞이 "A"로 시작하는 3개의 이름을 하나의 이름을 보아 "A 모음", "B", "C" 3개의 이름을 배열할 수 있습니다. 총 36가지의 경우가 있습니다.

 

 

이를 계산하기 위해 트라이 구조를 이용해보도록 합시다. 트라이에서 첫 번째 단계에 "A", "B", "C" 총 3개의 노드가 있으며, 자식이 있는 "A" 노드는 2개의 자식 노드가 있습니다. 다만, "A"로 시작하면서 바로 끝나는 노드를 세주기 위해, "A"에서 바로 끝난 이름도 추가로 세주면 3개가 됩니다. 이를 위해, 현재 트라이의 자식 노드를 곱하되, 현재 노드에서 끝나는 이름이 있을 경우, 1을 더해주면 됩니다. 코드에서는 isEnd라는 boolean 변수로 체크하고 있습니다.

 

 

 

 

 

 

 

코드

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import java.io.*;
 
public class Main {
 
    static final long INF = 1_000_000_007;
    static long[] fact = new long[3001];
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        calc(3000);
        TrieNode root = new TrieNode();
        for (int i = 0; i < N; i++) {
            root.insert(br.readLine());
        }
        System.out.println(root.count(root));
    }
 
    static class TrieNode {
        static final int MAX_SIZE = 26;
 
        TrieNode[] childNodes;
        boolean isEnd;
        int cnt;
 
        TrieNode() {
            childNodes = new TrieNode[MAX_SIZE];
        };
 
        void insert(String word) {
            TrieNode cur = this;
            for (int i = 0; i < word.length(); i++) {
                int letter = word.charAt(i) - 'A';
                if (cur.childNodes[letter] == null) {
                    cur.childNodes[letter] = new TrieNode();
                    cur.cnt++;
                }
 
                cur = cur.childNodes[letter];
                if (i == word.length() - 1) {
                    cur.isEnd = true;
                    return;
                }
            }
        }
        
        long count(TrieNode node) {
            if (node.cnt == 0return 1;
            long ret = (node.isEnd)? fact[node.cnt+1]: fact[node.cnt];
            for (int i = 0; i < 26; i++) {
                if (node.childNodes[i] != null ) {
                    ret *= count(node.childNodes[i]);
                    ret %= INF;
                }
            }
            return ret;
        }
    }
    
    static void calc(int N) {
        fact[0= 1;
        fact[1= 1;
        for (int i = 2; i <= N; i++) {
            fact[i] = (fact[i-1* i) % INF;
        }
    }
}
 
cs

 

'PS > Advanced String Manipulation' 카테고리의 다른 글

KMP 문제들 - 바킹독 문제집  (0) 2022.08.17
백준 1786번: 찾기 (JAVA)  (0) 2022.02.25