Sqsung DevLog

[백준] 20300번: 서강근육맨 - Node.js (자바스크립트) 본문

Algorithm

[백준] 20300번: 서강근육맨 - Node.js (자바스크립트)

sqsung 2023. 6. 9. 06:35

1. 문제 ㅡ 20300번: 서강근육맨 (난이도: Silver III)

 

20300번: 서강근육맨

PT 첫째 날에 $1$과 $4$를 선택하고, 둘째 날에 $2$와 $3$을 선택하고, 마지막 날에 $5$를 선택하면 $M$은 $5$가 되며, 이때가 $M$이 최소일 때이다.

www.acmicpc.net

2. 풀이 ㅡ Node.js (자바스크립트)

const [N, input] = require('fs').readFileSync('/dev/stdin').toString().trim().split('\n');
const machines = +N;
/**
* @BigInt 사용해야 함 
* 0 < 근손실을 나타내는 정수 < 10^18
* BigInt는 sort 메서드 안에서 -/+ 같은 연산자가 안되기 때문에 직접 비교해서 -1/1 반환 
*/ 
const losses = input
  .split(' ')
  .map(val => BigInt(val))
  .sort((a, b) => (a < b ? -1 : 1));

const getLeastLoss = () => {
  /**
  * 전체 기계 수가 짝수인 경우 그냥 0으로 초기화 
  * 전체 기계 수가 홀수인 경우 losses 배열에서 제일 큰 수로 초기화 및 해당 수 배열에서 제거 
  */ 
  let answer = machines % 2 === 0 ? 0 : losses.pop();
  let head = 0;
  let tail = losses.length - 1;

  while (head < tail) {
    if (losses[head] + losses[tail] > answer) answer = losses[head] + losses[tail];

    head += 1;
    tail -= 1;
  }

  // BigInt는 string으로 변환해서 반환해줘야 함
  return answer.toString();
};

console.log(getLeastLoss());

2-1. 풀이 설명

문제를 읽자마자 그리디 알고리즘을 사용해야 한다는 사실을 알아챘고, 풀이 과정도 쉬웠는데 계속 오답처리 되어서 예상보다 많은 시간이 걸린 문제다. 어떤 부분에서 틀렸는지 너무 헷갈려서 문제를 몇 번 더 읽어보니 각 기계 별 근손실을 나타내는 정수(M)가 '0 <= M <= 10^18' 범위 안에서 주어진다는 사실을 늦게 발견했다. BigInt를 사용해서 다시 제출하니 무사히 통과되었다. 

 

일반 숫자 타입 대신 BigInt를 사용하게 되면 주의할 점은 아래와 같다:

 

  •  BigInt는 sort 메서드 안에서 -/+ 연산자가 먹히지 않으므로 직접 a, b의 크기를 비교하여 -1, 1을 반환해야 함 
  • 마지막에 반환 값을 string 타입으로 바꿔서 반환해주지 않으면 에러처리 됨