Post

BOJ_1256_사전 (Java)

BOJ_1256_사전 (Java)

[Gold II] 사전 - 1256

문제 링크

성능 요약

메모리: 14240 KB, 시간: 104 ms

분류

조합론, 다이나믹 프로그래밍, 수학

제출 일자

2025년 2월 19일 00:49:23

문제 설명

동호와 규완이는 212호에서 문자열에 대해 공부하고 있다. 김진영 조교는 동호와 규완이에게 특별 과제를 주었다. 특별 과제는 특별한 문자열로 이루어 진 사전을 만드는 것이다. 사전에 수록되어 있는 모든 문자열은 N개의 "a"와 M개의 "z"로 이루어져 있다. 그리고 다른 문자는 없다. 사전에는 알파벳 순서대로 수록되어 있다.

규완이는 사전을 완성했지만, 동호는 사전을 완성하지 못했다. 동호는 자신의 과제를 끝내기 위해서 규완이의 사전을 몰래 참조하기로 했다. 동호는 규완이가 자리를 비운 사이에 몰래 사전을 보려고 하기 때문에, 문자열 하나만 찾을 여유밖에 없다.

N과 M이 주어졌을 때, 규완이의 사전에서 K번째 문자열이 무엇인지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 세 정수 N, M, K가 순서대로 주어진다.

출력

첫째 줄에 규완이의 사전에서 K번째 문자열을 출력한다. 만약 규완이의 사전에 수록되어 있는 문자열의 개수가 K보다 작으면 -1을 출력한다.

문제 풀이

combination 수를 구했다.

코드

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package BOJ_1256_사전;
        
/**
 * Author: nowalex322, Kim HyeonJae
 */

import java.io.*;
import java.util.*;

public class Main {
    static BufferedReader br;
    static BufferedWriter bw;
    static StringTokenizer st;
    static StringBuilder sb = new StringBuilder();
    static int N, M, K, res;
    static long combCnt;
    public static void main(String[] args) throws Exception {
        new Main().solution();
    }

    public void solution() throws Exception {
//        br = new BufferedReader(new InputStreamReader(System.in));
        br = new BufferedReader(new InputStreamReader(new FileInputStream("src/main/java/BOJ_1256_사전/input.txt")));
        bw = new BufferedWriter(new OutputStreamWriter(System.out));
        
        st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());

        combCnt = combCnt(N+M, N, M);
        if(K > combCnt) {
            System.out.println(-1);
            return;
        }

        int aCnt=N, zCnt=M;

        long cnt = 0;
        for(int i=0; i<N+M; i++){

            if(aCnt == 0) {
                sb.append('z');
                continue;
            }
            else if(zCnt == 0){
                sb.append('a');
                continue;
            }

            if(aCnt > 0) cnt = combCnt(aCnt + zCnt - 1, aCnt -1, zCnt);

            if(K <= cnt){
                System.out.println("cnt = " + cnt);
                sb.append('a');
                System.out.println(sb);
                aCnt--;
            }
            else{
                System.out.println("cnt = " + cnt);
                sb.append('z');
                System.out.println(sb);
                zCnt--;
                K -= cnt;
                System.out.println("K = " + K);
            }
        }
        System.out.println(sb);
        bw.flush();
        bw.close();
        br.close();
    }

    private long combCnt(int total, int a, int z) { // 조합 개수세기
        int m = Math.min(a, z);
        long cnt=1;
        for(int i=1; i<=m; i++) {
//            if(cnt >= Long.MAX_VALUE/(total-m+i)) return 1000000001;
            cnt = cnt * (total-m+i)/i;
            if(cnt > 1000000000) return 1000000001;
        }
        return cnt;
    }
}
This post is licensed under CC BY 4.0 by the author.