문제
BOJ9017_크로스 컨트리
코드
const filePath = process.platform === 'linux' ? '/dev/stdin' : './Javascript/input.txt';
const input = require('fs').readFileSync(filePath).toString().trim().split('\n');
const T = +input.shift();
for (let i = 0; i < T; i++) {
const N = +input[i * 2];
const players = input[i * 2 + 1].split(' ').map(Number);
solution(N, players);
}
function solution(N, players) {
const teams = new Set(players);
const teamObj = {};
[...teams].forEach((e) => (teamObj[e] = 0));
players.forEach((e) => (teamObj[e] += 1));
for (let teamNum in teamObj) {
if (teamObj[teamNum] < 6) delete teamObj[teamNum];
}
const scoreObj = {};
let score = 1;
players.forEach((num) => {
if (teamObj.hasOwnProperty(num)) {
if (scoreObj[num]) scoreObj[num].push(score++);
else {
scoreObj[num] = [];
scoreObj[num].push(score++);
}
}
});
for (let teamNum in scoreObj) {
const scoreToFour = scoreObj[teamNum].slice(0, 4).reduce((acc, cur) => (acc += cur), 0);
const scoreToFive = scoreObj[teamNum].slice(0, 5).reduce((acc, cur) => (acc += cur), 0);
scoreObj[teamNum] = [scoreToFour, scoreToFive];
}
const teamNums = Object.keys(teamObj);
let minScore = scoreObj[teamNums[0]];
let answer = teamNums[0];
for (let i = 1; i < teamNums.length; i++) {
if (minScore[0] === scoreObj[teamNums[i]][0]) {
minScore = minScore[1] < scoreObj[teamNums[i]][1] ? minScore : scoreObj[teamNums[i]];
answer = minScore[1] < scoreObj[teamNums[i]][1] ? answer : teamNums[i];
} else {
minScore = minScore[0] < scoreObj[teamNums[i]][0] ? minScore : scoreObj[teamNums[i]];
answer = minScore[0] < scoreObj[teamNums[i]][0] ? answer : teamNums[i];
}
}
console.log(answer);
}
풀이
- 팀별로 주자가 몇 명인지 구하여 '팀 번호-주자 수' 꼴로 객체에 저장한다.
const teams = new Set(players);
const teamObj = {};
[...teams].forEach((e) => (teamObj[e] = 0));
players.forEach((e) => (teamObj[e] += 1));
console.log(teamObj);

- 주자가 6명이 되지 않는 팀은 객체에서 제거해준다.
for (let teamNum in teamObj) {
if (teamObj[teamNum] < 6) delete teamObj[teamNum];
}
console.log(teamObj);

- 팀별로 각 주자의 점수를 구하여 '팀 번호-[주자들의 점수]' 꼴로 객체에 저장한다.
const scoreObj = {};
let score = 1;
players.forEach((num) => {
if (teamObj.hasOwnProperty(num)) {
if (scoreObj[num]) scoreObj[num].push(score++);
else {
scoreObj[num] = [];
scoreObj[num].push(score++);
}
}
});
console.log(scoreObj);

- 동점의 경우에는 다섯 번째 주자가 가장 빨리 들어온 팀이 우승하게 되므로 4번째 주자까지의 점수의 합과, 5번째 주자까지의 점수의 합을 각 팀별로 구해서 객체에 저장한다.
for (let teamNum in scoreObj) {
const scoreToFour = scoreObj[teamNum].slice(0, 4).reduce((acc, cur) => (acc += cur), 0);
const scoreToFive = scoreObj[teamNum].slice(0, 5).reduce((acc, cur) => (acc += cur), 0);
scoreObj[teamNum] = [scoreToFour, scoreToFive];
}

- 4번 주자까지의 점수의 합이 더 적은 팀의 번호를
answer 변수에 저장한다. 만약 4번 주자까지의 점수의 합이 같다면, 5번 주자까지의 점수의 합과 비교해서 점수가 더 적은 팀의 번호를 저장한다.
const teamNums = Object.keys(teamObj);
let minScore = scoreObj[teamNums[0]];
let answer = teamNums[0];
for (let i = 1; i < teamNums.length; i++) {
if (minScore[0] === scoreObj[teamNums[i]][0]) {
minScore = minScore[1] < scoreObj[teamNums[i]][1] ? minScore : scoreObj[teamNums[i]];
answer = minScore[1] < scoreObj[teamNums[i]][1] ? answer : teamNums[i];
} else {
minScore = minScore[0] < scoreObj[teamNums[i]][0] ? minScore : scoreObj[teamNums[i]];
answer = minScore[0] < scoreObj[teamNums[i]][0] ? answer : teamNums[i];
}
}
console.log(answer);

