ALGORITHM/BOJ

[백준] 1339 단어 수학

0298 2022. 2. 5. 23:39

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

 

1339번: 단어 수학

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

www.acmicpc.net

2022-02-25


1. 백트래킹

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
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
 
public class Main1339 {
    public static int N, answer;
    public static int[] arr, word;
    public static boolean[] vtd;
    public static HashSet<Character> set; // 중복 단어 거르기
    public static ArrayList<String> list; // 계산해아할 단어들
    public static void solve() {
        int calc = 0;
 
        for(int i = 0; i < list.size(); i++) {
            String str = list.get(i);
            int num = 0;
            for(int j = 0; j < str.length(); j++) {
                num *= 10;
                num += arr[str.charAt(j)-65];
            }
            calc += num;
        }
 
        answer = Math.max(answer, calc);
    }
 
    public static void comb(int cnt) {
        if(cnt == set.size()) {
            solve();
            return;
        }
 
        for(int i = 9; i >= 9-word.length+1; i--) {
            if(!vtd[i]) {
                vtd[i] = true;
                arr[word[cnt]] = i;
                comb(cnt+1);
                vtd[i] = false;
            }
        }
 
    }
 
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(bf.readLine().trim());
 
        N = Integer.parseInt(st.nextToken());
        set = new HashSet<>();
        list = new ArrayList<>();
        answer = 0;
 
        for(int i = 0; i < N; i++) {
            st = new StringTokenizer(bf.readLine().trim());
            String str = st.nextToken();
            // 중복 알파벳
            for(int j = 0; j < str.length(); j++) set.add(str.charAt(j));
 
            list.add(str);
        }
 
        List<Character> tmp = new ArrayList<>(set);
 
        word = new int[set.size()]; // 나온 단어들
        arr = new int[27]; // 단어 조합 만들 것
        vtd = new boolean[10];
        for(int i = 0; i < set.size(); i++) {
            word[i] = tmp.get(i) - 65;
        }
 
        comb(0);
 
        System.out.println(answer);
    }
}
cs

 

2. 수학

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
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
 
public class Main1339_2 {
    public static int N, answer;
    public static int[] arr;
    public static String[] word;
    public static HashSet<Integer> set;
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(bf.readLine().trim());
 
        N = Integer.parseInt(st.nextToken());
        arr = new int[26];
        word = new String[N];
        set = new HashSet<>();
 
        for(int i = 0; i < N; i++) {
            st = new StringTokenizer(bf.readLine().trim());
            String str = st.nextToken();
            word[i] = str;
            int num = 1;
            for(int j = str.length()-1; j >= 0; j--) {
                arr[str.charAt(j)-65+= num;
                num *= 10;
            }
        }
 
        Arrays.sort(arr);
 
        int val = 9;
        for(int i = arr.length - 1; i >= 0; i--) {
            answer += arr[i] * val--;
        }
 
        System.out.println(answer);
    }
}
cs

 

#문제풀이

 

1. 백트래킹

문제로 나온 N개의 단어들 중에서 중복을 제거한 알파벳들을 기준으로 만들 수 있는 모든 조합을 구했다. 그리고 9부터 차례대로 숫자를 부여해보고 합을 계산해 본 후, 그 합 중 최댓값을 출력했다. 

 

2. 수학

풀고 나서 다른 사람들 풀이를 보니, 백트래킹 브루트포스가 아닌 방법으로 푼 사람들이 있어서 그 방법으도 풀어봤다. 숫자들을 미리 다 자릿수를 합쳐서 계산한 후 정렬해서 큰 수 부터 차례대로 9, 8, 7, ..  숫자를 계산 해주었다. 

 

2
GCF
ACDEB

 

예를 들어

GCF의 경우 100G, 10C, 1F 이고 

ACDEB의 경우 10000A, 1000C, 100D, 10E, 1B이다. (line 25 ~ 28)

 

즉, 10000A, 1B, 1010C, 100D, 10E, 1F, 100G가 된다. 이걸 정렬 한 후 9부터 차례대로 숫자를 계산해주면 된다. (line 31 ~ 36)

 

 

2번 방법의 시간이 1번의 방법보다 1/10 줄었다.