[ BOJ / Python ] 1339번 단어 수학

황승환·2022년 1월 1일
0

Python

목록 보기
74/498

이번 문제는 접근을 초기에 잘못하는 바람에 코드를 새로 짜야했다. 처음에 접근한 방식은 입력된 문자열의 길이를 가장 긴 문자열과 같게 맞추기 위해 앞에 공백을 붙여 모든 문자열의 길이를 같게 만든 뒤에 모든 문자열의 첫번째 인덱스를 확인, 두번째 인덱스를 확인, ... 이 순서로 확인하며 알파벳을 순서대로 임시 배열에 저장한 뒤에 숫자를 저장하는 임시배열을 생성하여 9부터 알파벳 임시배열의 길이만큼 내림차순으로 배열에 수를 넣어주었다. 그리고 모든 문자열의 알파벳을 알파벳 임시 배열과 비교하여 알파벳 임시 배열과 같은 인덱스에 해당하는 숫자 배열의 값으로 문자열의 알파벳을 변경하여 이를 더하는 방식으로 코드를 짰었다. 그러나 반례를 찾아 본 뒤에 접근을 잘못했다는 사실을 깨달았다.

본인은 일차원적으로 무조건 자릿수가 큰 알파벳에 가장 큰 숫자가 들어가야 한다고 생각했지만 다음과 같이 ABB, BB, BB, BB, BB, BB, BB, BB, BB, BB의 경우에는 A에 9가 들어가 988이 된다면 B에는 8이 들어가 889=792가 되므로 1780라는 값이 나온다. 반면에 빈도수가 더 높은 B에 9가 들어가게 된다면 899와 999=891이 되고 1790이라는 값이 나온다.

우선 초기에 잘못 접근한 코드이다.

n=int(input())
words=[]
max_len=0
pri=[]
answer=0
for i in range(n):
    words.append(str(input()))
    max_len=max(len(words[i]), max_len)
for i in range(n):
    if len(words[i])<max_len:
        words[i]=' '*(max_len-len(words[i]))+words[i]
for i in range(max_len):
    for j in range(n):
        if words[j][i].isalpha() and words[j][i] not in pri:
            pri.append(words[j][i])
num=[str(a) for a in range(9,9-len(pri), -1)]
for i in range(len(pri)):
    for j in range(n):
        words[j]=words[j].replace(pri[i], str(num[i]))
for i in range(n):
    answer+=int(words[i])
print(answer)

새롭게 코드를 생각해보았지만 도저히 해결할 수가 없었기에 구글을 참고하였다. 본인이 초기에 작성한 코드가 자릿수만 고려했다면 새로운 코드는 자릿수와 빈도수를 함께 고려했다. 딕셔너리를 이용하여 key에 알파벳을 모두 넣어주고, value는 모두 0으로 초기화를 한 뒤에 문자열들을 순회하며 문자열의 각 알파벳들을 key로 하는 딕셔너리의 value에 자릿수를 더해주었다. 모든 문자열의 모든 알파벳에 대하여 이 과정을 끝내고 나면 value값이 0이 아닌 value들만 따로 임시 배열에 저장해주고 이를 내림차순으로 정렬한 뒤에 9부터 1씩 감소하는 값을 임시 배열의 첫번째부터 끝까지 곱해주며 모두를 더해주면 정답을 얻을 수 있다.

2
GCF
ACDEB
---------
A: 10000
B: 1
C: 1010
D: 100
E: 10
F: 1
G: 100
-->
10000 * 9 = 90000
1010 * 8 = 8080
100 * 7 = 700
100 * 6 = 600
10 * 5 = 50
1 * 4 = 4
1 * 3 = 3
  • n을 입력받는다.
  • 알파벳을 key로, 0을 value로 갖는 딕셔너리 alphabet을 선언한다.
  • value가 0이 아닌 value들을 담을 배열 lst를 선언한다.
  • 문자열을 저장할 배열 words를 선언한다.
  • 정답을 저장할 변수 answer를 0으로 정의한다.
  • n번 반복하는 i에 대한 for문을 돌린다.
    -> 문자열을 입력받아 words에 넣어준다.
  • words배열의 길이만큼 반복하는 i에 대한 for문을 돌린다.
    -> words[i]의 길이만큼 반복하는 j에 대한 for문을 돌린다.
    --> 임시 변수 num에 10의 words[i]의 길이-j-1승을 대입한다.
    --> alphabet[words[i][j]]의 value에 num을 더해준다.
  • alphabet 딕셔너리의 value를 순회하는 i에 대한 for문을 돌린다.
    -> 만약 i가 0보다 크다면 lst에 i를 넣어준다.
  • lst를 내림차순 정렬한다.
  • lst의 길이만큼 반복하는 i에 대한 for문을 돌린다.
    -> answer에 lst[i]*(9-i)를 더해준다.
  • answer를 출력한다.

Code

n=int(input())
alphabet={'A':0, 'B':0, 'C':0, 'D':0, 'E':0, 'F':0, 'G':0, 'H':0, 'I':0, 'J':0, 'K':0, 'L':0, 'M':0, 'N':0, 'O':0, 'P':0, 'Q':0, 'R':0, 'S':0, 'T':0, 'U':0, 'V':0, 'W':0, 'X':0, 'Y':0, 'Z':0}
lst=[]
words=[]
answer=0
for i in range(n):
    words.append(str(input()))
for i in range(len(words)):
    for j in range(len(words[i])):
        num=10**(len(words[i])-j-1)
        alphabet[words[i][j]]+=num
for i in alphabet.values():
    if i>0:
        lst.append(i)
lst.sort(reverse=True)
for i in range(len(lst)):
    answer+=(lst[i]*(9-i))
print(answer)

profile
꾸준함을 꿈꾸는 SW 전공 학부생의 개발 일기

0개의 댓글