본문 바로가기

백준/그리디

백준 1082 - 방 번호

728x90

www.acmicpc.net/problem/1082

 

가지고 있는 돈으로 만들 수 있는 가장 큰 수를 출력해야 한다.

 

0을 제외하고 0으로 시작하는 수가 없다고 한다.

 

이 문제는 양의 정수와 관련하여 다음과 같은 성질을 생각할 수 있다.

 

1. 자릿수가 많을수록 큰 수이다.

 

2. 어떤 두 수를 비교할 때 자릿수가 같다면 가장 앞에 자리가 큰 수가 더 크다.

 

이 두 성질을 통해 이 문제의 최적해를 구하기 위해서는 첫번째 숫자가 0이 되서는 안된다는 규칙을 지키면서 자릿수를 가능한한 크게 늘려야 하고, 자릿수를 늘릴 수 없다면 그 상태에서 수를 가장 크게 만들어야 한다.

 

이는 가장 싼 가격의 숫자를 최대한 많이 사서 자릿수를 늘리고 (첫번째 숫자는 0이 될 수 없다는 규칙을 지키면서) 자릿수를 최대한 늘리고 남은 나머지 돈으로 앞의 자리 숫자부터 최대한 큰 걸로 바꾸는 탐욕적인 방법으로 해결할 수 있다.

 

 

주어진 제한사항에 유의하여 trivial case를 세우고 방법을 구현하기만 하면 문제를 해결할 수 있다.

 

전체 코드

더보기
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
#include <bits/stdc++.h>
 
using namespace std;
using pii = pair<intint>;
 
int num_fee[10];
 
int main()
{
    memset(num_fee, -1sizeof num_fee);
    ios::sync_with_stdio(false);
    
    int n; cin >> n;
    vector<pii> v(n);
    
    for (int i = 0; i < n; ++i)
    {
        int x;
        cin >> x;
        num_fee[i] = x;
        v[i] = {x, i};
    }
    
    sort(v.begin(), v.end());
    
    int seed;
    cin >> seed;
    
    string res("");
    
    int idx = 0;
    
    if (!v[idx].second)
    {
        if (v.size() == 1 || v[idx + 1].first > seed)
        {
            cout << 0;
            return 0;
        }
        ++idx;
    }
    
    res.push_back(v[idx].second + '0');
    seed -= v[idx].first;
    idx = 0;
 
    while (seed - v[idx].first >= 0)
    {
        res.push_back(v[idx].second + '0');
        seed -= v[idx].first;
    }
    
    for (int i = 0; i < res.size(); ++i)
    {
        for (int j = 0; j < 10++j)
        {
            if (num_fee[j] == -1)
                continue;
            
            int cur = res[i] - '0';
            
            int diff = num_fee[j] - num_fee[cur];
            if (seed - diff >= 0 && cur < j)
            {
                seed -= diff;
                res[i] = char(j + '0');
            }
        }
    }
    
    cout << res;
}
cs

 

728x90

'백준 > 그리디' 카테고리의 다른 글

백준 1285 - 동전 뒤집기  (0) 2020.07.10
백준 17420 - 깊콘이 넘쳐흘러  (0) 2020.07.09
백준 1080 - 행렬  (0) 2020.06.21
백준 13458 - 시험 감독  (0) 2020.06.20
백준 1758 - 알바생 강호  (0) 2020.06.06