본문 바로가기

BOJ/C++

[BOJ] 사전

[문제]

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

 

1256번: 사전

첫째 줄에 N, M, K가 순서대로 주어진다. N과 M은 100보다 작거나 같은 자연수이고, K는 1,000,000,000보다 작거나 같은 자연수이다.

www.acmicpc.net

[풀이]

 

1256 맞았습니다!! 2144 KB 0 ms C++14 / 수정 1094 B 18분 전

 

1) 조합과 dp를 사용한다. 

 

2) 먼저 사전식 정렬을 생각해보면 알파벳 오름차순으로 정렬된다. (a -> z)

n= 3이고 m= 2일 경우 총 10가지의 경우의 수가 나온다. (n+mCm)

앞에서 6개까지는 a로 시작하는 문자열이고 7-10까지는 z로 시작하는 문자열이다. 

aaazz

aazaz

aazza

azaaz

azaza

azzaa

 

zaaaz

zaaza

zazaa

zzaaa

 

3) k의 범위를 잘 생각해야한다. k가 6보다 작을 경우 a로 시작하는 문자열이 정답이겠고, 아닐 경우 z로 시작하는 문자열일 것이다. 

a로 시작하는 문자열은 K를 다시 조절할 것없이 앞에서 부터 k번째의 문자열을 가져오면 되고, 

k가 6보다 큰 수라면 인덱스를 조절해야 한다. (k - n+mCm)

 

4) dp 이차원 배열에 미리 조합을 구해놓는다. 

nCr = n-1Cr-1 + n-1Cr

 

*조합과 디피라니.. 최악의 조합이었다. 

 


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
#include <iostream>
#define MAX_K 1000000000
using namespace std;
 
//ㅅㅏ전
 
typedef long long ll;
 
int n, m, dp[201][201]; //n = a의 개수 / m = b의 개수 / k번째 문자열
ll k;
 
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m >> k;
    /*
        사전은 a -> z 로 오름차순 정렬 
        조합을 생각해보면 n=2 m=2일 때 
        aazz
        azaz
        azza
        zaaz
        zaza
        zzaa
        -> n+mCm 이다. 
        K는 최대 6이 나올 수 있고, 3개까지는 a로 시작하는 문자열이고 
        그 이후로는 k-n+mCm을 한 값으로 구한다. 
     */
 
    for (int i = 0; i <= (m + n); i++)
    {
        dp[i][0= 1//nC0
        dp[i][i] = 1//nCn
    }
 
    //combination = nCr = n-1Cr-1 + n-1Cr
    for (int i = 2; i <= (n + m); i++)
    {
        for (int j = 1; j < i; j++)
        {
            dp[i][j] = dp[i - 1][j - 1+ dp[i - 1][j];
            if (dp[i][j] > MAX_K)
                dp[i][j] = MAX_K; //너무 커지지 않도록 조절
        }
    }
 
    int cnt = 0size = n + m;
    if (dp[n + m][m] < k)
        cout << "-1" << '\n';
    else
    {
        while (cnt < size)
        {
            if (k <= dp[n + m - 1][m])
            {
                //a로 시작함
                cout << "a";
                n--//a를 하나 썼으니까
            }
            else {
                k-= dp[n+m-1][m];
                cout << "z";
                m--;
            }
            cnt++;
        }
    }
    return 0;
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

'BOJ > C++' 카테고리의 다른 글

[BOJ] 캐슬디펜스  (0) 2019.08.08
[BOJ] 파이프옮기기1  (0) 2019.08.08
[BOJ] 발전소  (0) 2019.08.08
[BOJ] 게임  (0) 2019.08.07
[BOJ] 시험감독  (0) 2019.08.07