프론트엔드 개발자의 기록 공간

[백준 node.js] 1339번_단어 수학 본문

알고리즘_JS/백준_Greedy

[백준 node.js] 1339번_단어 수학

[리우] 2020. 12. 30. 16:43

백준 그리디 알고리즘 1339번_단어 수학

난이도 : 골드IV

 

문제 설명

입출력

 

문제 풀이 : 단어가 주어졌을때 해당 단어에 9부터 차례로 대입해서 최대값을 출력하면된다. ex )'GCFG' G:9, C:8 F:7(중복이면 큰값으로 설정)

개발로직

1. 단어의 길이에 따라 10의 거듭제곱으로 나타내준다. 'GCFG' G:1000, C:100, F:10 G:1 G는 중복되니깐 G: 1001, 나머지 그대로가 된다.

2. 이후 큰 값부터 정렬을한 뒤 9부터 대입해주면된다. 'GCFG' G(1001 * 9) + C(100 * 8) + F(10 * 7) = 9879

 

function solution(n, list) {
  let tmp = 0; //객체에서 value 의미
  //여기서 각각의 단어는 key가되고 해당자리수는 value가됨
  let result = {}; //객체 key value 담음
  let v = 0; //검색된 key의 value값

  //단어들의 개수만큼
  for (let i = 0; i < n; i++) {
    //각각의 알파벳만큼
    for (let j = 0; j < list[i].length; j++) {
      //tmp는 각 단어의 자리수만큼 제곱한 값이다 ex)1000, 100, ...
      //단어의 총 길이 - (j+1)를 해줘야지 해당하는 단어가 위치하는 자리수가 구해진다
      tmp = Math.pow(10, list[i].length - (j + 1));

      // (검색 in 객체)는 객체에 key가 있는지 검색하는 함수
      if ([list[i][j]] in result) {
        //result객체에 해당 단어가 있으면
        //v에 key에 해당하는 value값을 가져옴
        v = result[list[i][j]];
        //js 펼침 연산자(es6문법)
        //result에 기존 result를 복사해서 넣고 그중에서 원래있던 key(단어(list[i][j]))가 있으면 교체하고 
        //value값을 기존 value값 + 새로운 value값으로 대체
        result = { ...result, [list[i][j]]: v + tmp };
      } else {
        //객체에 겹치는 key(알파벳)이 없으면 key(알파벳) : value(자리수) 형식으로 넣어줌
        result = { ...result, [list[i][j]]: tmp };
      }
    }
  }
  //반복문을 빠져나오면 'A' : 1000 형식으로 들어가져있는데
  //이 값을 큰 값부터 9,8,7...곱해서 더해야한다. 즉 정렬이 필요하다.
  //객체를 value값에 따라 key값과 함께 정렬할려면 이차원배열에 삽입후 배열을 정렬해줘야한다
  
  //key, value값을 이차원배열에 삽입
  let sortlist = [];
  for (let i in result) {
    sortlist.push([i, result[i]]);
  }
  console.log(sortlist);
  //2차원배열에서 value값에따라 정렬
  sortlist.sort(function (a, b) {
    return b[1] - a[1];
  });

  let cnt = 9;
  let sum = 0;
  //반복문을 통해 value값에 9부터 카운트해주면서 곱해줌
  for (let k = 0; k < sortlist.length; k++) {
    sum += sortlist[k][1] * cnt;
    cnt -= 1;
  }
  console.log(sum);
}

const readline = require("readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let input = [];
rl.on("line", function (line) {
  //여러줄 입력
  input.push(line);
}).on("close", function () {
  let n = parseInt(input[0]);
  let list = input.slice(1);
  solution(n, list);
  process.exit();
});

 

* 이번문제는 혼자 생각하면서 짜다보니깐 생각보다 비효율적으로 짠거같다는 생각이 들었다.

'GCFG' G:1001, C:100, F:10 이런형식으로 나타내야하다보니깐 key, value쌍이 생각이 났고 객체로 짜야겠다고 생각이 들어서 풀었다. 객체 형식을 많이 안써봐서 중간중간 문법을 많이 찾아보면서 했다. js문법이 많이 부족하다는 것을 느꼈다.

어찌저찌해서 key, value 형태로 로직을 짜고 큰값대로 정렬을 해야했다. 하지만 객체에서 value를 정렬할려면 배열에 따로 담아 해줘야되어서 새로운 이차원 배열에 key, value를 삽입후 정렬을 하고 계산을 해주었다.

 

이렇게 해서 문제를 풀고나서 코드를 보니 너무 찜찜해서 방법을 바꿀려고 해보았다.

객체를 사용해서 정렬할때 배열로 다시 넣어줄빠에 처음부터 이차원배열에 key, value형태로 넣어보자 생각해서 바꿔보았다. 하지만 처음에 알파벳별로 접근하기 위해 이중for문을 도는데 그안에서 key값을 검색할려면 또 for문이 필요해서 3중 for문이 필요했고 기존값을 삭제하고 다시 넣기 위해 여러 함수가 필요했다.

그래서 기존의 코드대로 진행했다. 블로그 작성이 끝나면 다른 사람들의 로직을 보면서 개선해나가야겠다.

728x90
Comments