몸과 마음이 건전한 SW 개발자

Softeer [Level 3] 루돌프 월드컵 {언어 : JavaScript} [반올림 주의] 본문

알고리즘/풀었지만 다시 보기

Softeer [Level 3] 루돌프 월드컵 {언어 : JavaScript} [반올림 주의]

스위태니 2024. 11. 2. 00:09

문제 링크

https://softeer.ai/practice/7721

 

Softeer - 현대자동차그룹 SW인재확보플랫폼

 

softeer.ai

정답 코드

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

const inputData = [];

rl.on('line', (line) => {
    inputData.push(line.split(" ").map((e) => Number(e)));
}).on('close', () => {
    let answer = 0;
    const powers = inputData[0];
    const winRate = (i, j) => {
        return (4 * powers[i]) / (5 * (powers[i] + powers[j]));
    }
    const check = (arr) => {
        const newArr = arr.map((e, idx) => [e, idx]);
        newArr.sort(([a, b], [c, d]) => a - c || d - b);
        return newArr[2][1] === 0 || newArr[3][1] === 0;
    }
    const dfs = () => {
        const stack = [[0, 1, 1, [0, 0, 0, 0]]];
        while (stack.length) {
            const [i, j, rs, scores] = stack.pop();
            if (i === 4) {
                if (check(scores)) {
                    answer += rs;
                }
                continue;
            }
            if (j === 4) {
                stack.push([i+1, i+2, rs, scores]);
                continue;
            }
            const winS = scores.slice();
            winS[i] += 3;
            stack.push([i, j+1, rs*winRate(i, j), winS]);
            
            const drawS = scores.slice();
            drawS[i] += 1;
            drawS[j] += 1;
            stack.push([i, j+1, rs*0.2, drawS]);
            
            const defeatS = scores.slice();
            defeatS[j] += 3;
            stack.push([i, j+1, rs*winRate(j, i), defeatS]);
        }
    } 
    dfs();
    console.log((answer*100).toFixed(3));
    process.exit(0);
});

풀이 방법

  1. 1번 루돌프 부터 dfs 탐색을 시작한다.
    1. 1번 루돌프는 2번 루돌프, 3번 루돌프, 4번 루돌프와 승무패를 계산한다.
    2. 1번 루돌프가 2번 루돌프와 겨뤘을 때
      1. 이긴 경우
      2. 비긴 경우
      3. 진 경우
    3. 1번 루돌프가 4번 루돌프를 지나면 이제 i를 1올려주고 j는 i에서 2올려준다.
      1. 이유는 자기 자신을 제외하고 1번은 이미 만났기 때문에 3번부터 계산하기 위함이다.
  2. 탐색을 하면서 확률과 승점을 기록한다.
  3. 승점순으로 나열한 뒤 1번이 상위 2등 안에 드는지 확인하고 answer에 더한다.
  4. 100을 곱한 뒤 toFixed를 사용해서 세번째 소수점까지 반올림하여 출력하면 끝!

느낀점

  • 처음엔 answer에 10만을 곱하고 반올림한 뒤에 1000으로 나눴는데 틀렸다.
  • 틀린 이유를 살펴보면 확률이 5%라면 5.000으로 나와야 하는데 5만 표시되서 틀렸다.