[백준/C++]#11005 - 진법 변환2

2021. 1. 25. 12:28필요/코딩테스트(백준)

 

 

풀이

#include <iostream>
using namespace std;

int main() {
	long long n;	// 10억까지 가능한 n 정의
	int b, i;
	long long a[10000000];	
	cin >> n >> b;
	for (i=0; n/b!=0; i++) {	// 나누기 및 나머지 연산 계산
		a[i]=n%b;
		n/=b;
	}
	a[i] = n%b;
	for (; i>=0; i--) {		// 반복된 수만큼 재출력
		if (a[i]==10) cout << "A";		// 10~35 값 입력시 해당 문자 출력
		else if (a[i]==11) cout << "B";
		else if (a[i]==12) cout << "C";
		else if (a[i]==13) cout << "D";
		else if (a[i]==14) cout << "E";
		else if (a[i]==15) cout << "F";
		else if (a[i]==16) cout << "G";
		else if (a[i]==17) cout << "H";
		else if (a[i]==18) cout << "I";
		else if (a[i]==19) cout << "J";
		else if (a[i]==20) cout << "K";
		else if (a[i]==21) cout << "L";
		else if (a[i]==22) cout << "M";
		else if (a[i]==23) cout << "N";
		else if (a[i]==24) cout << "O";
		else if (a[i]==25) cout << "P";
		else if (a[i]==26) cout << "Q";
		else if (a[i]==27) cout << "R";
		else if (a[i]==28) cout << "S";
		else if (a[i]==29) cout << "T";
		else if (a[i]==30) cout << "U";
		else if (a[i]==31) cout << "V";
		else if (a[i]==32) cout << "W";
		else if (a[i]==33) cout << "X";
		else if (a[i]==34) cout << "Y";
		else if (a[i]==35) cout << "Z";
		else cout << a[i];		// 0~9 값은 그대로 출력
	}
	return 0;
}

개념

이번 수학 문제는 진법 변환 문제이다.

다음 그림은 십진수 11을 3진법으로 변환한 예이다.

 

 

11은 3진법으로 102 이다.

다른 진법들도 마찬가지로 계산가능하다.


풀이 

일단 생각되는 걱정거리는 두 개이다.

하나는 나머지 계산을 하는 순서와 반대로 출력되는 것이고, 둘째는 11~36진법은 알파벳으로 출력해야한다는 것이다.

다음과 같은 방식으로 문제를 해결했다.

 

1. for문을 사용해 더이상 n이 b에 나눠지지 않을 때까지 배열에 나머지를 대입한다.

 

2. 배열에 넣은 순서와 반대로, 여태껏 반복한 횟수만큼 출력한다.

 

3. 이 때 if문을 사용해 11~35를 알파벳으로 출력한다.

 

for문의 특성상 조건을 탈출하면서, 한번의 계산이 덜 시행되어서 따로 추가했다.

 


+a

for문안의 i 값 자체를 재활용하는 건 처음인데, 놀랍게도 for문을 나갈 때 알아서 ++된다. (for문의 i++를 거치는 듯)

따라서 굳이 a[++i] = n%b; 를 하지않고 a[i] = n%b; 로 충분했다.

 

 배열의 크기는 처음엔 n의 크기인 10억으로 했으나, 런타임 오류가 발생했다.
따라서 런타임 오류가 나지않는 선에서 최대한 큰 값으로 지정하였다.
가장 많은 계산이 발생하는 예시를 보면, 10억을 2의 제곱으로 표현하면 2의 30제곱정도이다.
배열의 크기는 그정도로 잡아도 문제없을 것 같다.
* 나중에 확인하기

사실 풀면서도 든 생각인데, 뭔가 잘못되고 있다는 것을 느꼈다.

다만 달리 생각나는 풀이가 없어서 if문을 알차게 사용했다.

 

백준에서 제시한 아주 깔끔한 풀이를 보았다.

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

int main() {
    int n, b;
    cin >> n >> b;
    string ans =  "";
    while (n > 0) {
        int r = n % b;
        if (r < 10) {
            ans += (char)(r + '0');
        } else {
            ans += (char)(r - 10 + 'A');
        }
        n /= b;
    }
    reverse(ans.begin(),ans.end());
    cout << ans << '\n';
    return 0;
}

인간미는 없지만 아주 깔끔하다.

algorithm 라이브러리를 사용해서 reverse 기능을 수행했다.

그것보다 중요한 것은 string을 통한 값처리이다.

이러한 문제를 자주 보긴했는데, 아스키코드 변환에 관한 문제는 직접 풀기가 쉽지 않다...