🖥️ CS/SW Expert 외의 Algorithms

프로그래머스 n진수 게임 (C++)

한국의 메타몽 2021. 9. 8. 01:32

문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/17687

 

코딩테스트 연습 - [3차] n진수 게임

N진수 게임 튜브가 활동하는 코딩 동아리에서는 전통적으로 해오는 게임이 있다. 이 게임은 여러 사람이 둥글게 앉아서 숫자를 하나씩 차례대로 말하는 게임인데, 규칙은 다음과 같다. 숫자를 0

programmers.co.kr

 

문제 요약

 

1. 숫자를 0부터 시작해서 차례대로 말한다. 첫 번쨰 사람은 0, 두 번째 사람은 1, ... 열 번째 사람은 9를 말한다.

2. 10이상의 숫자부터는 한 자리씩 끊어서 말한다. 즉, 열 한번째 사람은 10의 첫 자리인 1, 열 두 번째 사람은 둘째자리인 0을 말한다.

3. 게임의 난이도를 높이기 위해 각 숫자는 n진법으로 변환하여 답한다.

4. 이 게임에는 m명이 참가하며, 튜브가 미리 구해야할 숫자는 t개이다. 튜브의 순서가 p일때 튜브가 말해야하는 숫자들을 문자열로 출력하라.

 

 

핵심 포인트

 

0부터 n까지의 숫자를 n진법으로 변환한 뒤, 튜브의 순서에 따른 정답을 따로 추출해내는 것이 관건입니다.

또한 아래 출력형식을 유의하여 10이상의 값은 아스키코드를 활용하여 문자형으로 변환해야합니다.

미리 구해야할 숫자 t * 게임에 참가하는 순서 m을 문자열의 전체 길이로 보면 좀 더 쉽게 접근할 수 있습니다.

 

 

문제 풀이

 

먼저 전체 로직을 훑어보겠습니다.

#include <string>
#include <vector>
#include <algorithm>

string s = "";

void conversion(int n, int i){ // 2
    if(i==0) s+='0';
    string temp = "";
    while(i>0){
        if(i%n<10) temp += (i%n)+'0';
        else temp += (i%n)-10+'A';
        i/=n;
    }
    reverse(temp.begin(),temp.end());
    s+=temp;
}

string solution(int n, int t, int m, int p) { // n진법, 미리구할 숫자 갯수, 게임에 참가하는 인원, 튜브의 순서
    string answer = "";
    int num = 0, temp = 0, cnt = 0;
    for(int i=0; i<t*m; i++){ // 1
        conversion(n, i);
    }
    for(int i=0; i<t*m; i++){ // 3
        if((i+1)%p==0){ 
            answer += s[i];
            p+=m;
        }
    }
    return answer;
}

 

1. 0부터 t*m까지 각 숫자들을 n진법으로 변환합니다.

conversion의 매개변수 n은 n진법, i는 n진법으로 변환해야하는 숫자 i를 뜻합니다.

    for(int i=0; i<t*m; i++){
        conversion(n, i);
    }

 

 

2. 다음은 n진법으로 변환하는 과정입니다.

string s = "";

void conversion(int n, int i){
    if(i==0) s+='0';  // 1
    string temp = ""; 
    while(i>0){ // 2
        if(i%n<10) temp += (i%n)+'0'; // 3
        else temp += (i%n)-10+'A'; // 4
        i/=n; // 5
    }
    reverse(temp.begin(),temp.end()); // 6
    s+=temp; // 7
}

(1)  숫자가 0일 경우, 그대로 문자로 변환하여 저장합니다.

(2) 그렇지 않을 경우 i가 0을 초과할때까지 while문을 진행합니다.

(3) i%n<10일경우, 그대로 문자로 변환하여 저장하면 됩니다.

(4) 그렇지 않을 경우, 아스카코드 값에 따라 값을 변환해야합니다. (ex : 10 -> A, 11 -> B)

(i%n)-10을 한 뒤 'A'를 더해주면 10은 A, 11은 B의 값으로 변환되어 문제에서 제시하는 출력형식을 맞출 수 있습니다.

(5) i/=n으로 값을 나눠줍니다.

(6) 그렇게 완성된 temp는 순서를 역으로 뒤집어 줍니다.

(7) s에 temp를 저장합니다.

 

3. 다음은 정답을 저장하는 과정입니다.

    for(int i=0; i<t*m; i++){
        if((i+1)%p==0){ // 1
            answer += s[i]; // 2
            p+=m; // 2
        }
    }

(1) i는 0부터 시작하므로, (i+1)%p가 0인 경우에만 튜브가 미리 구해야하는 정답에 해당됩니다.

(2) 정답에 해당 문자를 추가하고 다음 순서를 갱신해줍니다.

 

4. 정답을 반환합니다.