🔒 문제
민식이는 수학학원에서 단어 수학 문제를 푸는 숙제를 받았다.
단어 수학 문제는 N개의 단어로 이루어져 있으며, 각 단어는 알파벳 대문자로만 이루어져 있다. 이때, 각 알파벳 대문자를 0부터 9까지의 숫자 중 하나로 바꿔서 N개의 수를 합하는 문제이다. 같은 알파벳은 같은 숫자로 바꿔야 하며, 두 개 이상의 알파벳이 같은 숫자로 바뀌어지면 안 된다.
예를 들어, GCF + ACDEB를 계산한다고 할 때, A = 9, B = 4, C = 8, D = 6, E = 5, F = 3, G = 7로 결정한다면, 두 수의 합은 99437이 되어서 최대가 될 것이다.
N개의 단어가 주어졌을 때, 그 수의 합을 최대로 만드는 프로그램을 작성하시오.
⌨ 입력
첫째 줄에 단어의 개수 N(1 ≤ N ≤ 10)이 주어진다. 둘째 줄부터 N개의 줄에 단어가 한 줄에 하나씩 주어진다. 단어는 알파벳 대문자로만 이루어져있다. 모든 단어에 포함되어 있는 알파벳은 최대 10개이고, 수의 최대 길이는 8이다. 서로 다른 문자는 서로 다른 숫자를 나타낸다.
🖨 출력
첫째 줄에 주어진 단어의 합의 최댓값을 출력한다.
📚 예제
Ex1)
2
AAA
AAA
1998
Ex2)
2
GCF
ACDEB
99437
Ex3)
10
A
B
C
D
E
F
G
H
I
J
45
Ex4)
2
AB
BA
187
📌 풀이
각 줄에 주어진 단어의 각 자리수를 일의 자리, 십의 자리, 백의 자리,,, 로 생각해서 풀었다.
Ex2)를 예로 들어 GCF에서 G는 백의 자리, C는 십의 자리, F는 일의 자리이고
ACDEB에서, A는 만의 자리, C는 천의 자리, D는 백의 자리, E는 십의 자리, B는 일의 자리이다.
각 문자가 0 ~ 9 중 어떤 수를 사용해야 최대값이 나올지는 바로 알 수 없으니 한 문자가 사용된 각 자리 수 들만을 defaultdic에 저장했다.
위의 예를 다시 가져와서 설명하자면
- GCF
문자 (Key) | 사용된 자리수들 (Value) |
---|---|
C | 10 |
F | 1 |
G | 100 |
- ACDEB
앞의 딕셔너리에 추가해주는 것이므로,
문자 (Key) | 사용된 자리수들 (Value) |
---|---|
A | 10000 |
B | 1 |
C | 1010 |
D | 100 |
E | 10 |
F | 1 |
G | 100 |
C는 GCF와 ACDEB에 둘다 있기 때문에, 10에 1000이 더해진 것을 확인할 수 있다.
이 중 value값 만을 꺼내서 list로 만들고 내림차순으로 정렬을 한 다음, 각 인덱스에 저장된 값과 9 ~ 0을 각각 곱해서 다 더하면 답이 된다.
위의 예시로 다시 설명하자면,
value | 숫자 ( 0 ~ 9) | 곱한 값 |
---|---|---|
10000 | 9 | 90000 |
1010 | 8 | 8080 |
100 | 7 | 700 |
100 | 6 | 600 |
10 | 5 | 50 |
1 | 4 | 4 |
1 | 3 | 3 |
곲한 값들을 다 더하면 99437로 답이 나오게 된다.
defaultdict를 사용한 이유
defaultdict를 사용한 이유는 각 문자열이 사용된 자리수를 기록하기 위해서 문자열 리스트를 만들어서 그 문자가 기록된 위치를 찾으면 시간 복잡도가 증가할 것 같아서였다. 딕셔너리는 key값을 넣으면 바로 value값이 나와서 시간 복잡도가 O(1)이기 때문이다.
+) defaultdic을 사용하지 않고 일반 dictionary를 사용해도 될 것 같다.
+) dict가 싫다면, 아스키 코드 A가 65인 것을 사용하여, list를 알파벳 개수(26)개로 만들고 [대문자 아스키 코드 -65]를 인덱스로 사용하여 list에 접근해도 좋을 것 같다
ex) 예시 코드
alpha = [0 for _ in range(26)]
if(문자 == C):
index = int(C) - 65
alpha[index] += 1
🔑 python 코드
import sys
from collections import defaultdict
N = int(sys.stdin.readline())
arr = [list(sys.stdin.readline()) for _ in range(N)]
arr.sort(key = lambda x : len(x), reverse = True)
ans = 0
alphabet = defaultdict(int)
for i in range(N):
for j in range(len(arr[i]) - 1):
alphabet[arr[i][j]] += 10**(len(arr[i]) - 2 - j)
value = list(alphabet.values()) # 딕셔너리 value값 리스트로 변경
value.sort(reverse = True)
for i in range(len(value)):
ans += value[i] *(9 - i)
print(ans)