[골드 4] 1339번 단어 수학

Doozuu·2023년 11월 7일
0

백준 (NodeJS)

목록 보기
31/56

문제 설명

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

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

출력

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

규칙 정리

  • 각 알파벳을 0 ~ 9 사이 숫자로 바꿈(숫자는 중복되면 안 됨)
  • 알파벳을 숫자로 바꿔서 N개의 수를 합함
  • 합이 최대가 되도록 만들기

풀이

  • 리스트 중에 가장 자릿수가 큰 수를 찾기
  • 앞에서부터 순서대로 가장 큰 수 부여하기

예시 )

GCF
ACDEB

최대 5자리 수
5일 때 : A : 9
4일 때 : C : 8
3일 때 : D,G -> 7,6
2일 때 : C,E -> E : 5
1일 때 : F,B -> 4,3

  1. input을 순회하면서 가장 높은 자리수 찾기
  2. 가장 높은 자리수-- 하면서 리스트에 해당 값이 있으면 해당 알파벳에 숫자 부여
  3. 숫자 더하기

-> 예제는 맞았지만 테스트에서 틀렸다.
-> 단순히 자리수가 크다고 해서 가장 큰 숫자를 부여하면 되는게 아니다.
-> 만약 AB와 B 90개가 주어진다면 98 + 80 보다 89 + 90가 더 크기 때문이다.

const input = require("fs").readFileSync("ex.txt").toString().split("\n");
const [N, ...list] = input;

let max_length = 0;
list.forEach((el) => (max_length = Math.max(max_length, el.length)));

let map = new Map();
let number = 9;

const reversed_list = list.map((el) => [...el].reverse());

for (let i = max_length - 1; i >= 0; i--) {
  reversed_list.map((el) => {
    if (!!el[i] && !map.get(el[i])) {
      map.set(el[i], number.toString());
      number--;
    }
  });
}

let sum = 0;
let transform = list.map((el) =>
  [...el].reduce((acc, cur) => acc + map.get(cur), "")
);
sum = transform.reduce((acc, cur) => +acc + +cur, 0);
console.log(sum);

풀이 개선

  1. 각 자리수에 숫자 부여하고 더하기
AAA
BCD

3의 자리 수 = 100
2의 자리 수 = 10
1의 자리 수 = 1
{ 'A' => 111, 'B' => 100, 'C' => 10, 'D' => 1 }
2. 내림차순으로 정렬하기
3. 9~0까지 순서대로 곱해서 더하기

const input = require("fs").readFileSync("ex.txt").toString().split("\n");
const [N, ...list] = input;

const map = new Map();
let number = 10;

// 각 자리수에 숫자 부여하고 더하기
list.map((item) =>
  [...item].map((a, idx) => {
    const val = map.get(a);
    map.set(a, (val || 0) + 10 ** (item.length - idx - 1));
  })
);

const mapEntries = Array.from(map);
// 내림차순 정렬하기
let sortedMap = mapEntries.sort((a, b) => b[1] - a[1]);
// 9부터 순서대로 곱해서 누적합 구하기
let answer = sortedMap.reduce((acc, cur) => {
  number--;
  return acc + cur[1] * number;
}, 0);

console.log(answer);
profile
모든게 새롭고 재밌는 프론트엔드 새싹

0개의 댓글