[Javascript] 프로그래머스 level2 - 예상 대진표

ckxo·2023년 8월 12일
0

programmers

목록 보기
19/29

문제 설명

△△ 게임대회가 개최되었습니다. 이 대회는 N명이 참가하고, 토너먼트 형식으로 진행됩니다. N명의 참가자는 각각 1부터 N번을 차례대로 배정받습니다. 그리고, 1번↔2번, 3번↔4번, ... , N-1번↔N번의 참가자끼리 게임을 진행합니다. 각 게임에서 이긴 사람은 다음 라운드에 진출할 수 있습니다. 이때, 다음 라운드에 진출할 참가자의 번호는 다시 1번부터 N/2번을 차례대로 배정받습니다. 만약 1번↔2번 끼리 겨루는 게임에서 2번이 승리했다면 다음 라운드에서 1번을 부여받고, 3번↔4번에서 겨루는 게임에서 3번이 승리했다면 다음 라운드에서 2번을 부여받게 됩니다. 게임은 최종 한 명이 남을 때까지 진행됩니다.

이때, 처음 라운드에서 A번을 가진 참가자는 경쟁자로 생각하는 B번 참가자와 몇 번째 라운드에서 만나는지 궁금해졌습니다. 게임 참가자 수 N, 참가자 번호 A, 경쟁자 번호 B가 함수 solution의 매개변수로 주어질 때, 처음 라운드에서 A번을 가진 참가자는 경쟁자로 생각하는 B번 참가자와 몇 번째 라운드에서 만나는지 return 하는 solution 함수를 완성해 주세요. 단, A번 참가자와 B번 참가자는 서로 붙게 되기 전까지 항상 이긴다고 가정합니다.

제한사항

N : 21 이상 220 이하인 자연수 (2의 지수 승으로 주어지므로 부전승은 발생하지 않습니다.)
A, B : N 이하인 자연수 (단, A ≠ B 입니다.)

입출력 예

NABanswer
8473

입출력 예 설명

입출력 예 #1

첫 번째 라운드에서 4번 참가자는 3번 참가자와 붙게 되고, 7번 참가자는 8번 참가자와 붙게 됩니다. 항상 이긴다고 가정했으므로 4번 참가자는 다음 라운드에서 2번이 되고, 7번 참가자는 4번이 됩니다. 두 번째 라운드에서 2번은 1번과 붙게 되고, 4번은 3번과 붙게 됩니다. 항상 이긴다고 가정했으므로 2번은 다음 라운드에서 1번이 되고, 4번은 2번이 됩니다. 세 번째 라운드에서 1번과 2번으로 두 참가자가 붙게 되므로 3을 return 하면 됩니다.

풀이

2명씩 짝 지어 대진하는데 입출력 예시 1번을 보면 알 수 있듯, 각 번호의 참가자는 다음 라운드 때 (자신의 번호/2)의 반올림한 번호를 받는다. 또한 두 참가자가 붙게 되었을 때 부여받는 번호는 2로 나눈 후 반올림하였을 때 같은 값이 나올 것이다. 이를 이용해 문제를 풀면 된다.

첫 번째 코드(실패)

가장 처음은 while문으로 작성했다.

이땐 반올림을 생각 못하고, 홀수일 경우 1을 더해서 2로 나누어주고 짝수일 경우 바로 2로 나누어 주는 식으로 진행했다. 또한 문제를 제대로 읽지 않고 테스트 케이스만 확인하면서 정답보다 1이 적은 숫자가 나오길래, 반복문 이전에 answer를 1로 설정해주는 바보같은 짓을 했다.

function solution(n,a,b)
{
    var answer = 1;
    
    while(n){
        if(b-a===1) break;
        
        a = (a%2===1) ? (a+1)/2 : a/2;
        b = (b%2===1) ? (b+1)/2 : b/2;
        answer++;
    }

    return answer;
}

성공(14/34), 실패(1/34), 시간초과(19/34)

두 번째 코드(실패)

두 번째는 For문을 써봤다. 확실히 while문 보다는 빠른 듯 했다.

function solution(n,a,b)
{
    var answer = 1;
    
    for(let i=0; i<n; i++){
        if(b-a===1) break;
        
        a = (a%2===1) ? (a+1)/2 : a/2;
        b = (b%2===1) ? (b+1)/2 : b/2;
        answer++;
    }

    return answer;
}

성공(14/34), 실패(20/34)

그리고 여기서 answer을 0으로 하면 전체 실패가 뜨는 걸 깨닫고 코드 자체가 잘못되었음을 알게 되어 아예 새롭게 코드를 다시 짰다.

세 번째 코드(성공)

function solution(n,a,b)
{
    var answer = 0;
    
    while(a!==b){
        a = Math.ceil(a/2);
        b = Math.ceil(b/2);
        answer++;
    }

    return answer;
}

0개의 댓글