코테

백준 2745번 진법 변환 (C++)

hhzn 2025. 3. 19. 14:06

이전 포스팅들은 각 단계별로 묶어서 업로드 했는데, 
각 문제들에서 시사할 바와 내가 고민한 바 등등 적고싶은게 많아졌다.

한 문제당 고봉밥(최대한;;)으로 업로드 하는 형식으로 변경하려고 한다. 

 

이번 단계의 제목은 <일반 수학1> 이다.

개인적인 의견으로 수학적 사고력이 필요한 문제라고 생각한다.

나는 문제들에서 주어진 것이 무엇인지, 내가 구해야 하는 것이 무엇인지를 생각하면서 풀었다.

 


https://www.acmicpc.net/problem/2745

 

2745번

 

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;


int main()
{
	string N;
	int B;
	cin >> N >> B;

	vector<unsigned int> v;
	
	for (const char& elem : N) {
		char num = elem;
		if (elem >= 'A') {
			num = elem - 'A' + 10;
		}
		else {
			num = elem - '0';
		}
		v.push_back(num);
	}

	unsigned int answer = 0;

	for (long i = 0; i < v.size(); ++i) {
		answer += v[i] * pow(B, v.size() - 1 - i);
	}

	cout << answer;
}

입력으로 들어오는 수는 최대 36진법으로 들어올 수 있다.

알파벳 대문자의 형태로 주어질 수 있으니, string 형으로 입력받는다.

 

문자열의 각 문자들을 순회하여 조건을 검사한다.

문자가 'A' 보다 크다면, 알파벳 대문자의 형태로 들어온 것이다. 이를 정수형으로 변환한다.

주어진 문자에서 'A' 만큼 빼면 0 부터 25까지의 수를 얻을 수 있다. 

알파벳 대문자를 사용하는 이유는 10진법을 넘어가는 진법을 수로 표현하기 위함으로 10을 더해주면 해당 수를 10진법의 형태로 얻을 수 있다.

 

문자가 'A' 보다 크지 않다면, 숫자의 형태로 들어온 것이다.

string으로 입력받았기 때문에 이를 단순히 정수형으로 변환하기만 하면 안된다.

(해당 숫자에 대응하는 아스키코드의 값이 저장된다.)

이를 방지하기 위해서 '0' 을 빼주면 정수형의 값을 얻을 수 있다.

 

여기까지 각 자리의 수들을 10진법으로 변환하는 과정을 수행했다. 

그러니까.. 예를 들면 36진법의 ZZZZZ 라는 수를 35/35/35/35/35 까지 변환했다는 것이다.

변환한 수들의 자리 정보도 포함해서 완전하게 변환해야 한다. 

n의 자리(여기서 n은 입력받은 수인 N과 다름)의 수는 B의 n제곱을 곱해주면 10진법의 수로 얻을 수 있다.

for (long i = 0; i < v.size(); ++i) {
	answer += v[i] * pow(B, v.size() - 1 - i);
}

여기 for 문이 해당 작업을 수행한다. 

우리가 일반적으로 생각하는 n의 자리는 좌측부터 시작하는데,

string 으로 받은 문자를 우측부터 변환해서 저장했기 때문에 제곱을 할 때 반대로 해주어야 한다.

 

모든 자리를 순회해서 이 작업에서 결과로 나오는 수들을 모두 더해준다. 

그럼 B 진법 수를 10 진법으로 변환할 수 있다!


이 문제를 풀면서 내가 범했던 실수들은 

 

1. 컴파일 에러

 : pow 를 사용하기 위해서는 <cmath> 를 추가해야 한다.

2. for 문에서 n의 자리 수와 내가 push_back 한 수의 자리가 반대로 저장되는 것을 망각했다. 
예제 입력 ZZZZZ 는 모든 자리의 수가 같기 때문에 해당 오류를 바로 잡아내지 못했다. 

 

3. 알파벳으로만 이루어진 수를 생각했다. 

char 를 정수형으로 변환할 때 냅다 - 'A' + 10 만 해주어서 0부터 9의 숫자가 들어오면 엉뚱한 수로 변환되었음.

 


마치며

 

컴파일 에러는 진짜 아닌 것 같다.. 

 

 


** 오류 지적은 환영입니다.^^ **