브실이의 입시전략_29723

박상민·2024년 7월 10일
0

백준

목록 보기
33/36
post-thumbnail

난이도 : 실버 5
소요시간 : 30분

문제 설명

문제이해

  • 브실대에 합격조건은 특정과목들의 성적의 합을 통해 합격여부 결정
  • 단, 브실대에서는 어떤 과목이 서류평가에 반영되는지는 일부과목만 알려줌
  • 브실이가 수강한 과목과 점수, 그리고 브실대에서 알려주는 일부과목을 토대로 브실이가 얻을 수 있는 최소 점수와 최대 점수를 구하는 문제

예제풀이

  • 첫번째 줄에 브실이가 수강한 과목 수 6, 브실대에서 요구하는 과목수 3, 브실대에서 공개한 과목 수 2
  • 두번째 줄부터는 브실이가 수강한 6개의 과목에 대한 정보가 "과목명 점수" 로 입력
  • 그 이후는 브실대에서 공개한 2개의 과목이 차례로 입력됨
  • 브실이가 먼저 얻을 수 있는 점수는 physics점수 + python점수를 합친 50+90 = 140이고
    나머지 한 과목에 대한 최솟값은 probability(70), 최댓값은 calculus(100) 또는 algorithm(100)이다.
  • 따라서 최솟값 140+70 = 210, 최댓값 140+100 = 240으로 210 240이 출력된다.

아이디어

  • 브실이가 수강한 과목에서 브실대에서 공개한 과목 수를 제외한 나머지 과목에서 점수가 가장 낮은 과목의 점수와 가장 높은 과목의 점수를 더하면 된다.
  • 문제에서 '공개된 과목과 비공개된 과목은 브실이가 수강한 과목에 모두 포함되어 있다고 하였으므로' 브실대에서 공개한 K개의 과목은 브실이가 수강한 N개의 과목에 모두 포함되어 있다.
  • 따라서 브실이가 수강한 과목 중 브실대에서 공개한 과목의 수만 골라내 합산을 하고 제거한 다음 나머지 과목중에서 최대와 최소를 찾으면 되는 문제로 해석해보았다.

문제 풀이

1. 입력파싱

// 입력
const [N, M, K] = input[0].split(' ').map(Number);
// 브실이가 수강한 과목과 점수
const subjects = input.slice(1, N + 1).map((subject) => subject.split(' '));
// 브실대에서 공개한 과목
const publicSubjects = input.slice(N + 1, N + K + 1);

2. 과목 점수 맵에 저장

let subjectMap = new Map();
subjects.forEach(([s, p]) => {
    subjectMap.set(s,+p);
});
  • subjects.forEach(([s, p]) => { ... })는 각 과목과 점수 쌍을 순회하며 Map에 저장합니다.
  • +p는 문자열을 숫자로 바꾸는 암묵적 변환

3. 공개된 과목 점수 합산 및 삭제

// 공개된 과목의 점수를 합산하고 subjectMap에서 제거
let openSubjectScore = 0;
publicSubjects.forEach((t) => {
    openSubjectScore += subjectMap.get(t);
    subjectMap.delete(t);
});

4. 남은 과목들의 점수 정렬

// 남은 과목들의 점수를 오름차순으로 정렬
let remainingSubjects = Array.from(subjectMap.values()).sort((a, b) => a - b);

5. 남은 과목에서 최솟값과 최댓값 계산

let minScore = 0, maxScore = 0;

// 남은 과목에서 최솟값과 최댓값 계산
for (let i = 0; i < M - K; i++) {
    minScore += remainingSubjects[i];
    maxScore += remainingSubjects[remainingSubjects.length - 1 - i];
}
  • publicSubjects.forEach((t) => { ... })는 각 공개된 과목을 순회하며, 해당 과목의 점수를 subjectMap에서 가져와 합산
  • subjectMap.delete(t)를 사용하여 공개된 과목을 Map에서 제거합니다. 이는 나중에 남은 과목을 처리할 때 중복을 피하기 위함

6. 최종 결과 출력

// 최종 결과 출력
console.log(openSubjectScore + minScore, openSubjectScore + maxScore);

정답코드

const fs = require('fs');
const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';

const input = fs.readFileSync(filePath).toString().split('\n');

//입력
const [N, M, K] = input[0].split(' ').map(Number);

//브실이가 수강한 과목과 점수 
const subjects = input.slice(1, N+1).map((subject) => subject.split(' '));

// console.log(subjects);
//브실대에서 공개한 과목
const publicSubjects = input.slice(N+1, N+K+1);

// 브실이의 입시전략
let subjectMap = new Map();
subjects.forEach(([s, p]) => {
    subjectMap.set(s, +p);
});

// publicSubjects 배열을 순회하면서 공개된 과목의 점수를 합산합니다.
// 공개된 과목의 점수를 subjectMap에서 가져와 openSubjectScore에 더하고, 
// 해당 과목을 subjectMap에서 삭제합니다.
let openSubjectScore = 0;
publicSubjects.forEach((t) => {
    openSubjectScore += subjectMap.get(t);
    subjectMap.delete(t);
});

// 남은 과목들의 점수를 오름차순으로 정렬하고, 가장 낮은 점수부터 가장 높은 점수까지 더해줍니다.
let remainingSubjects = Array.from(subjectMap.values()).sort((a, b) => a - b);
let minScore = 0, maxScore = 0;
for (let i = 0; i < M - K; i++) {
    minScore += remainingSubjects[i];
    maxScore += remainingSubjects[remainingSubjects.length - 1 - i];
}

console.log(openSubjectScore + minScore, openSubjectScore + maxScore);
profile
I want to become a UX Developer

0개의 댓글