[3차] n진수 게임

유태형·2022년 2월 12일
0

문제

문제 분석

예전에 1의 개수를 비교하던것과 달리 여러 진수들이 나누어 질 수 있으므로 직접 진수를 구하는 로직을 구성해야 한다. 구성한 다음 순서에 맞춰 값들을 추가하자!




풀이

n진법

오랫만이기도 하고 해서 나머지 연산을 사용한다는건 알았는데 간단하게 또 문자를 이용하여 10진수 이상은 기억이 안나기도 해서 애를 먹었고 다른 분의 블로그를 참조하였다.

private static StringBuilder convertNum(int num, int n){
   StringBuilder sb = new StringBuilder();
   if(num==0)
       return sb.append(0);
   
   while(num != 0){
       int mod = num % n;
       if(mod >= 10){
           int idx = 'A' + (mod-10);
           sb.append((char)idx);
       }
       else
           sb.append(mod);
       num /= n;
   }
   
   //거꾸로 출력
   return sb.reverse();

}

if(mod >= 10)로 자리수가 한자리냐 두자리냐로 구분 뒤 두자리면int idx = 'A' + (mod-10);를 이용하여 10이 넘는 수를 문자로 전환하고(-10은 앞자리 1을 제거) StringBuilder에 추가, 또 자리수가 StringBuilder내부에서 거꾸로이니 .reverse()메소드를 호출함으로써 자리수 맞춤

StringBuilder sb = new StringBuilder();
   for(int num=0; num<=t*m; num++){ //t*m개 만큼
       
       // n진수화
       StringBuilder tmp = convertNum(num,n);
       sb.append(tmp);
   }

t는 문자갯수, m은 참가자수이다. num은 최대한의 경우를 고려해야 하므로, 모든 수가 자리수를 넘어가지 않을때(한 차례당 한 값 일 떄) 최대한 많은 값의 수를 가질 것이다. 따라서 t * m

순서 값 찾기

1.n진법으로 변경도 시키고
2.최대한 나올 수 있는 갯수 만큼 값들도 입력하였으면
3.순서에 맞는 숫자(값들의 자리수)들만 골라내서 답에 추가시켜야 한다.

StringBuilder result = new StringBuilder();
   for(int i=0;i<sb.length();i++){
       if(result.length() >= t) break;
       
       if(((i+1)%m) == (p%m)){
           result.append(sb.charAt(i));
       }
   }

먼저 변수들을 정리해 보자
t = 예상해야할 숫자의 갯수
m = 참가자 수
p = 나의 순서(몇번째로 뽑는가)

다른 분의 블로그를 참조 하였을때 ((i+1) % m) == (p % m)가 가장 헷갈렷고 이해하기 어려웠다.
p은 몇 번째 순서인지에 대한 값이다.
(i+1)인덱스는 0부터 시작하지만 순서는 1부터 시작한다. 즉 1번째가 0번 인덱스, 2번째가 1번 인덱스, ......n번째가 n-1번째 인덱스를 사용할 것이기에 +1을 해준다.

% m 마지막 순서 이후 다시 처음 순서로 돌아가기 위해서 필요하다.




코드

class Solution {
    public String solution(int n, int t, int m, int p) {
        StringBuilder answer = new StringBuilder();
        

        StringBuilder sb = new StringBuilder();
        for(int i =0; i < t*m; i++){ //t:말해야하는 숫자갯수 , m: 참가자 수, t*m: 최대치
            String temp = convertNum(i,n); //N진수로 치환
            sb.append(temp);
        }
        
        //길이 만큼 구함
        for(int i = 0; i < sb.length();i++){
            if(answer.length() >= t) break; //튜브가 t개만큼 말하면 끝
            
            //튜브의 차례면 추가, p%m : 튜브의 순서
            if((i+1)%m == p%m) answer.append(sb.charAt(i));
        }
        //튜브가 말한 문자열
        return answer.toString();
    }
    
    //10진수 num -> n진수 num으로 변환
    private String convertNum(int num, int n){
        StringBuilder sb = new StringBuilder();
        if(num == 0) return "0"; //0은 그대로 0
        
        //0일때 까지
        while(num != 0){
            int mod = num % n; //나머지 구하기
            if(mod >= 10){ //나머지가 2자리
                mod = 'A' + (mod-10); //문자로 치환
                sb.append((char)mod);
            }else //나머지가 1자리
                sb.append(mod);
            num /= n; //다음 자리 수
        }
        
        //1의 자리부터 순서대로 저장되었으므로 순서를 뒤집음
        return sb.reverse().toString();
    }
}

챙겨 볼 것:StringBuilder




GitHub

https://github.com/ds02168/Study_Algorithm/blob/master/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/%EC%9E%90%EB%B0%94/Level2/n%EC%A7%84%EC%88%98%EA%B2%8C%EC%9E%84.java

profile
오늘도 내일도 화이팅!

0개의 댓글

관련 채용 정보