본문 바로가기
코딩테스트 공부/Programmers

[C++] level2 [3차] n진수 게임 17687

by 메정 2021. 8. 21.

📌n진수 게임

/* 해당 문제 설명은 링크로 대체한다. */

해설을 보면 다음과 같다

반복문과 진법 변환을 할 수 있다면 어렵지 않게 풀 수 있는 문제입니다. 진법 변환은 프로그래밍 언어를 처음 배울 때 연습 문제로 많이 풀어봤을 문제일 텐데요. 오래간만에 풀어보려니 쉽지만은 않았던 듯 싶습니다.
참고로 이 문제는 챔퍼나운 수라는 수학 상수를 이용한 문제입니다.
이 문제의 정답률은 91.85%였습니다. 대부분 잘 풀어주셨으나, 언어별로는 C++ 사용자들이 약간 어려워했습니다.

📌풀이

  1. 1부터 구해야 하는 문자열 t * m 만큼 반복문을 돌면서 전체 문자열str 구함

    • 2진수는 반복문을 통해서 구하는데 num % n의 값이 10 이상이라면 A, B, C, D, E, Ftemp에 담음
    • 2진수(0,1)의 경우 나머지부터 넣으면 순서를 바꿔줘야 하므로 reverse() 함수 이용
  2. 구한 문자열 중에서 내가 말해야 하는 순서p에 맞는 문자열만 모아ans 출력

    • 처음에 이 부분을 p % 2 가 짝수인 경우, 홀수인 경우로 나눠서 생각해 보았는데 그러면 오류가 발생했다.
    • 다양한 시도 끝에 p - i + i * m 으로 접근하면 내가 말하는 순서로 접근할 수 있다.

📌코드

#include <string>
#include <vector>
#include <algorithm>
using namespace std;

string calBit(int n){ //2진수, 16진수로 변환
    if(n <= 9) return to_string(n);
    switch(n){
        case 10 : return "A"; break;
        case 11 : return "B"; break;
        case 12 : return "C"; break;
        case 13 : return "D"; break;
        case 14 : return "E"; break;
        case 15 : return "F"; break;
    }
    return "";
}

string solution(int n, int t, int m, int p) {
    string str = "", ans = "";
    int cnt = 0;

    // 1) 전체 문자열 완성(str)
    while(1){
        string temp = ""; //각 숫자별 진수 변환 
        int num = cnt++;
        while(1){
            temp += calBit(num % n);
            num /= n;
            if(num == 0) break;
        }
        reverse(temp.begin(), temp.end()); //진수 변환을 위한 순서 변경
        str += temp;
        if(str.size() > t * m) break; //m명인데 t만큼 말해야하니까 이 경기는 t * m 만큼 진행ㅇㅇ
    }

    // 2) 내 차례일 때 말해야하는 문자열 구하기
     for(int i = 0; i < t; i++)
        ans += str[p - 1 + i * m];

    return ans;
}   

회고

어렵지 않은 문제임에도 시간을 많이 두고 고민했다.
진법 계산해서 담는 것까지 괜찮았는데 내 차례일 때 말해야 하는 문자열을 구하는데 시간이 오래 걸렸다.

아직 한참 멀고도 멀었다.


댓글