진번 기초 문제
본문 바로가기
알고리즘 최종 (단계별)/1.수학

진번 기초 문제

by KyeongMin 2023. 6. 27.
728x90
반응형

진법

  • 진법 변환을 해보자.
  • N 이 주어진 경우 B진법이라면 B로 N을 나눈 나머지를 저장해서 거꾸로 출력하면됨
  • 이때 10이상인 경우 10은 A로 표현 하여 Z까지 표현 가능함
  • 필자는 문자을 출력하는 것을 아스키코드를 이용하여 문제 풀이진행
    • 대문자 A의 아스키코드는 65이다.
    • 그럼 10이 나오면 +55하면 대문자 아스키코드 65를 만족하게됨 이를 이용해서 풀던지
    • 또다른 방법
      • 10미만인 경우 값에 +’0’ 을 더하면되고,
      • 10이상인 경우 +’A’를 해주면된다.
        • 이렇게 되는 것은 문자열 아스키 코드가 49인데 이때 ‘0’이 48이기때문에 그냥 일반 숫자에 이값을 더하게되면 이를 만족하기 때문이다.
          • 단, 이때 -10을 해줘야한다는것은 잊지 말아라.

11005_진법 변환 2

#include<stdio.h>
#include<iostream>
#include<vector>
using namespace std;

int main(void) {
	//char a = 10+55;
	//cout << a << endl;
	int N, B;
	cin >> N >> B;
	vector<char>result;
	while (1) {
		char nModB = N % B;
		result.push_back(nModB);
		N = N / B;
		if (N == 0)break;
	}

	for (int i = result.size() - 1; i >= 0; i--) {
		if (result[i] >= 10) printf("%c", result[i] + 55);
		else printf("%d", result[i]);
	}
	return 0;
}
  • 위의 소스는 필자가 해결한 첫 번째 방법이다.
  • 두번째 ‘0’, ‘A’를 더하는 경우
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

int main(void) {
	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;
}

진법 변환

  • B 진법을 다시 10진법으로 바꾸자.

2745_진법 변환

11 3

11/3 2
3/3 0
1

1 * 3 + 0 = 3
3 * 3 + 2 = 11

---
14 3

14/3 = 2
4/3 = 1
1

1 * 3= 3
3 * 3 + 1

1 * 3 + 1 = 4
4 * 3 + 2 = 14
  • 처음 숫자와 B를 곱하고 다음 값을 더한다.
  • 그리고 이를 반복한다.
  • 소스코드 구현
#include<iostream>
#include<string>
using namespace std;

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

	int ret = 0;

	for (int i = 0; i < N.size(); i++) {
		if (N[i] >= 'A') ret = ret * B + (N[i] - 'A' + 10);
		else ret = ret * B + (N[i] - '0');
	}
	cout << ret << '\\n';
	return 0;
}

1373_2진수 8진수

  • 문제링크
  • https://www.acmicpc.net/problem/1373
  • 문제풀이
    • 2진법 10진법으로 바꾼다 그리고 8진법으로 변경한다.
    • 그럼 위에 두가지를 응용해서 구현해보자.
      • 위에처럼 생각하면 틀릴것이다. 우선 길이가 엄청 길기때문에 그렇게 하면 안됨
    • 포인트는 8진수이면 3비트씩 쪼개면된다.
      • 순서대로 값을 1,2,4를 가지게 되는데 이를 계산하면
      • 101 인경우 41 + 20 + 1*1 = 5 라는 8진수로 표현 할 수 있다.
      • 아래는 그것을 소스코드로 옮긴 것이다.
  • 소스코드
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int main(void) {
	string N;
	string ret;
	cin >> N;
	reverse(N.begin(), N.end());
	int threeCheck[] = { 0,1,2,4 };

	int sum = 0;
	for (int i = 0, cnt = 1; i < N.size(); i++,cnt++) {
		if (N[i] == '1')sum += threeCheck[cnt];

		if (cnt == 3) {
			ret += to_string(sum);
			cnt = 0;
			sum = 0;
		}
	}
	if (N.size() % 3 != 0) {
		ret += to_string(sum);
	}
	reverse(ret.begin(), ret.end());
	cout << ret << endl;
	return 0;
}
  • 더 간략한 풀이법
#include <iostream>
#include <string>
using namespace std;
int main() {
    string s;
    cin >> s;
    int n = s.size();
    if (n%3 == 1) {
        cout << s[0];
    } else if (n%3 == 2) {
        cout << (s[0]-'0')*2 + (s[1]-'0');
    }
    for (int i=n%3; i<n; i+=3) {
        cout << (s[i]-'0')*4 + (s[i+1]-'0')*2 + (s[i+2]-'0');
    }
    cout << '\\n';
    return 0;
}
  • 사이즈가 1인경우 그냥 그대로를 출력
  • 2개인 경우 2개에 대해서만 계산
  • 3개이상인 경우 각 자리를 3자리씩 이동하면서 계산하는 식이다.

1212_8진수 2진수

  • 문제 링크
  • 문제 풀이
    • 314이 있다면 이것은 이런식으로 풀면됨
    • 각 경우를 저장을 해서 사용하면됨
    • 0→000
    • 1 ⇒ 001
    • 2⇒ 010
    • 3⇒ 011
    • 4→ 100
    • 5→101
    • 6→110
    • 7→111
  • 소스 코드
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
using namespace std;

int main(void) {
	map<char, string> twoRule;
	twoRule['0'] = "000";
	twoRule['1'] = "001";
	twoRule['2'] = "010";
	twoRule['3'] = "011";
	twoRule['4'] = "100";
	twoRule['5'] = "101";
	twoRule['6'] = "110";
	twoRule['7'] = "111";

	string N;
	cin >> N;
	string ret;
	for (int i = 0; i < N.size(); i++) {
		ret += twoRule[N[i]];
	}
	//reverse(ret.begin(), ret.end());

	if (ret[0] == '0') ret.erase(ret.begin(), ret.begin() + 1);
	if (ret[0] == '0') ret.erase(ret.begin(), ret.begin() + 1);

	cout << ret << '\\n';
	return 0;
}
  • 이렇게 해도됨
#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
string eight[8] = {"000","001","010","011","100","101","110","111"};
int main(){
    string s;
    cin >> s;
    bool start = true;
    if (s.length() == 1 && s[0]-'0' == 0) {
        cout << "0";
    }
    for (int i=0; i<s.length(); i++) {
        int n = s[i]-'0';
        if (start == true && n < 4) {
            if (n == 0) {
                continue;
            } else if(n == 1) {
                cout << "1";
            } else if (n == 2) {
                cout << "10";
            } else if (n == 3) {
                cout << "11";
            }
            start = false;
        } else {
            cout << eight[n];
            start = false;
        }
    }
    return 0;
}
728x90
반응형

댓글