Koder / 박성훈
article thumbnail

USACO(4)

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

 

2089번: -2진수

-2진법은 부호 없는 2진수로 표현이 된다. 2진법에서는 20, 21, 22, 23이 표현 되지만 -2진법에서는 (-2)0 = 1, (-2)1 = -2, (-2)2 = 4, (-2)3 = -8을 표현한다. 10진수로 1부터 표현하자면 1, 110, 111, 100, 101, 11010, 110

www.acmicpc.net

진수 변환 방법에 대해서 먼저 숙지해야 하는 문제.

10진수 >> 2진수 변환을 계산할수 없으신 분들이라면

이 문제를 잡기 전에 2진수 변환 먼저 배우고 오는 것이 좋다고 생각한다.

 

일반적인 2진수 변환은

2로 나눈 나머지를 저장하고

숫자를 2씩 나눠간 다음

저장한 값들을 뒤집어서 출력해준다.

 

-2진수 변환도 크게 다를것이 없다.

-2로 나눈 나머지를 저장하고,

숫자를 -2로 나눠가면서 계산한 다음

저장한 값들을 뒤집어서 출력해준다.

 

-2진수 변환이 2진수 변환과 다른 것은,

-2로 나눈 나머지가 -1이 될수 있다는 것이다.

 

나머지를 0과 1 단 두가지만 남겨주어야

이 나머지를 저장한 다음 뒤집어서 출력해줄 수 있기 때문에,

 

예시로 제공된 -13의 경우

(-2 * 6) + (-1) 이 아닌 (-2 * 7) + (1) 으로 변환해주는 과정이 필요하다.

즉, 나머지가 -1인 경우 몫을 1 올려주고, 나머지를 2 올려주는 연산을 추가적으로 진행해주면

 

-13 = (-2*7) + 1

7    = (-2*-3) + 1

-3   = (-2*2) + 1

2    = (-2*-1) + 0

-1   = (-2*1) + 1

1    = (-2*0) + 1

으로,

저장되는 순서는 111011, 뒤집어 출력하면 110111으로 정답을 구할 수 있게 된다.

 

이렇게 0이 될때까지 나눠가는 방법을 택하면,

입력으로 0이 주어지는 경우에

아무런 연산을 하지 않기 때문에

이부분을 따로 처리해주면 문제를 해결할 수 있다.

 

소스코드 펼쳐보기

더보기
#include <bits/stdc++.h>
using namespace std;

// -13 -> -2*7 + 1
// 7   -> -2*-3 + 1
// -3  -> -2*2 + 1
// 2   -> -2*-1 + 0
// -1  -> -2*1 + 1
// 1   -> -2*0 + 1

stack<int> s;

int main(){
	int N;
	cin >> N;
	
	do{
		int tmp = N%-2;
		N /= -2;
		
		if(tmp<0){
			N++;
			tmp = 1;
		}
		s.push(tmp);
	}while(N);
	
	while(!s.empty()){
		cout << s.top();
		s.pop();
	}
	return 0;
}

반응형