알고리즘/BOJ 문제풀이

[Greedy] BOJ 1339 단어 수학

4Legs 2020. 12. 2. 01:43

문제 링크 : www.acmicpc.net/problem/1339

 

1339번: 단어 수학

첫째 줄에 단어의 개수 N(1 ≤ N ≤ 10)이 주어진다. 둘째 줄부터 N개의 줄에 단어가 한 줄에 하나씩 주어진다. 단어는 알파벳 대문자로만 이루어져있다. 모든 단어에 포함되어 있는 알파벳은 최대

www.acmicpc.net

이 문제가 그리디 알고리즘으로 해결할 수 있다는 것을 캐치한다면,

일반적으로는 더 자릿수가 큰 수의 앞 자리 알파벳부터 큰 수를 부여하는 식의 접근을 할 것이다.

하지만 이러한 접근의 경우 각종 예외 케이스들을 관통하는 하나의 코드를 구현하기 매우 까다롭다.

 

예를 들어 ABC와 BB 9개, 총 10개의 단어에 대해

A = 9, B = 8, C = 7 이라면 987 + 88 * 9 = 1,779

A = 8, B = 9, C = 7 이라면 897 + 99 * 9 = 1,788 로,

더 긴 단어의 앞 자리 알파벳이 크다고 반드시 최댓값을 내지 않음을 알 수 있다.

 

이 문제를 백트래킹이 아닌 그리디 알고리즘으로 해결하기 위해서는 문제를 좀 더 간단화할 필요가 있다.

단어 ABCD는 1000A + 100B + 10C + D 로 나타낼 수 있으며,

각 단어들을 모두 위와 같이 나타내어 합하면 각 알파벳들을 미지수로 하는 하나의 식이 나온다.

이 식에서 계수가 가장 높은 순서대로 큰 수를 부여하면 문제를 해결할 수 있다.

 

[코드]

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
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
 
using namespace std;
typedef pair<intint> p;
 
int n;
vector<string> words;
vector<p> coef;
int curval = 9;
 
void get_coef(string s) {
    int exp = 0;
    for (int i = s.size() - 1; i >= 0; i--) {
        int letter = s[i] - 'A';
        coef[letter].first += pow(10, exp++);
    }
}
 
void init() {
    string input;
    cin >> n;
 
    for (int i = 0; i < n; i++) {
        cin >> input;
        words.push_back(input);
    }
 
    //총합의 계수와 알파벳을 저장
    for (int i = 0; i < 26; i++) coef.push_back({ 0, i });
}
 
bool cmp(p a, p b) {
    return a.first > b.first;
}
 
int main() {
    int result = 0;
    init();
 
    for (int i = 0; i < words.size(); i++) get_coef(words[i]);
 
    //계수를 내림차순으로 정렬
    sort(coef.begin(), coef.end(), cmp);
 
    for (int i = 0; i < coef.size(); i++) {
        result += coef[i].first * curval;
        curval--;
    }
 
    printf("%d\n", result);
 
    return 0;
}
cs

 

'알고리즘 > BOJ 문제풀이' 카테고리의 다른 글

[Greedy] BOJ 1781 컵라면  (0) 2020.12.03
[Greedy] BOJ 1700 멀티탭 스케줄링  (0) 2020.12.02
[Floyd] BOJ 1602 도망자 원숭이  (0) 2020.11.30
[Floyd] BOJ 2610 회의준비  (0) 2020.11.29
[Floyd] BOJ 10159 저울  (0) 2020.11.29