12주차 #1339 단어수학

Yona·2021년 11월 11일
2

🍕 baekjoon

목록 보기
14/31

✉️ 문제

백준링크

민식이는 수학학원에서 단어 수학 문제를 푸는 숙제를 받았다.

단어 수학 문제는 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이다. 서로 다른 문자는 서로 다른 숫자를 나타낸다.

출력
첫째 줄에 주어진 단어의 합의 최댓값을 출력한다.

예시

  • 입력1
    2
    AAA
    AAA

  • 출력1
    1998

(999+999)

  • 입력2
    2
    GCF
    ACDEB

  • 출력2
    99437

💬 문제를 보고 든 생각

  1. 가장 자주 나오는 단어가 가장 높은 숫자를 가져가면 되겠구만
  2. 근데 이제 가장 '높은 자리 수'에 오는 단어도 가장 높은 숫자를 가져가야겠다

✔️ 첫번째 시도

def my_pow(target_num, power_num) :
  if power_num == 0 : return 1
  result = target_num
  for i in range(power_num-1) :
    result *= target_num
  return result


# 데이터 입력
N = int(input())
input_alpha = []
for i in range(N) :
  input_alpha.append(input())

di = {'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}

# 가중치기준 출현횟수*출현자릿수(10단위)
for i in range(N) :
  for s in input_alpha[i] :
    s_len = len(s)
    for i in range (s_len) :
      di[s[i]] += my_pow(10, (s_len-i-1))
      
# value 기준 정렬
di.items()
di=sorted(di.items(), key=lambda x: x[1], reverse=True)


result_di = {}
# 높은 value를 가진 item 들에게 순서대로 9~1을 부여
for i in range(10) :
  result_di[di[i][0]] = 9-i


# input data를 딕셔너리에 부여된 숫자에 따라 계산한다
result = 0
for s in input_alpha :
  s_len = len(s)
  for i in range(s_len) :
    result += result_di[s[i]]*my_pow(10, (s_len-i-1))


print(result)

입력예시 1, 3 같은 경우는 올바른 출력이 나오는데

2
GCF
ACDEB

는 99437 이 나와야하는데 90051 이 결과로 나온다.
최적의 결과를 못찾아냈다 😢
= 놓친 케이스가 있는거임
= 내가 세운 가중치에 따라 번호 부여하는게 잘못된거임

✔️ 두번째 시도

  1. 가중치를 두어서 거기에 맞추어 숫자를 부여한다는게
    효율적으로 하고 싶다는건데, 그런거 없이 그냥 모든 케이스를 다 검사해보고, 그 중 제일 큰 값으로 결정하도록 해야겠다.
  2. 그리고 power 연산 이거 내가 함수 만들 필요없이 ** 으로 계산된다 ㅎㅎ..
  3. 그러고 모든 케이스 검사 하도록 하는데, 아무리 봐도 내가 만든 가중치가 그렇게 이상한것같지는 않아서 코드를 다시 봄

# 데이터 입력
N = int(input())
input_alpha = []
for _ in range(N) :
  input_alpha.append(input())

di = {'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}

# 가중치기준 출현횟수*출현자릿수(10단위)
#for i in range(N) :
#  for s in input_alpha[i] :
#    s_len = len(s)
#    for i in range (s_len) :
#      di[s[i]] += my_pow(10, (s_len-i-1))

for s in input_alpha:
    for i in range(len(s)):
        num = 10 ** (len(s) - i - 1)
        di[s[i]] += num

      
# value 기준 정렬
di.items()
di=sorted(di.items(), key=lambda x: x[1], reverse=True)


result_di = {}
# 높은 value를 가진 item 들에게 순서대로 9~1을 부여
for i in range(10) :
  result_di[di[i][0]] = 9-i


# input data를 딕셔너리에 부여된 숫자에 따라 계산한다
result = 0
for s in input_alpha :
  s_len = len(s)
  for i in range(s_len) :
    result += result_di[s[i]]*my_pow(10, (s_len-i-1))


print(result)

그냥 for문을 이상하게 짠거였다
for i in range <-> for i in arr 를 왠만해선 혼용해서 쓰지말자 아놔

profile
Sometimes you win, sometimes you learn 🏃‍♀️

1개의 댓글

comment-user-thumbnail
2021년 11월 11일

아놔 굿굿

답글 달기