새소식

💻 Programming (프로그래밍)/C++ | 백준

[C++][백준] - 유학 금지 (2789번)

  • -

 

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

2789번: 유학 금지

아주 멀리 떨어져 있는 작은 나라가 있다. 이 나라에서 가장 공부를 잘하는 학생들은 모두 다른 나라로 유학을 간다. 정부는 최고의 학생들이 자꾸 유학을 가는 이유를 찾으려고 했다. 하지만,

www.acmicpc.net

🔔 문제 : 

입력으로 주어진 단어를

"CAMBRIDGE" 이중 포함되는 알파벳을 없앤후 출력하면 되는 문제입니다.

 

입력값 LOVA -> 출력값 LOV


🔔 Kick Point :

 

각 알파벳을 넣어줘서, for문을 통해 일치하는 값이 있다면 입력값을 제한해주었습니다.

 

하지만 이런 코드는 또 너무 길고 지저분해서 다른 분들의 숏코딩을 찾아보았습니다.

 

비트연산자를 사용하는 코드를 발견하고 써먹어야겠다 싶어서 올립니다.

 

1. 쉽게 for문 사용

C++11이상 언어스타일은 for_each 반복문을 사용할 수 있습니다.

for(char c : str) 을 통하여 string를 순회할 수 있습니다.

 

for(자료형 변수명 : 배열명) { 실행 코드 }

 

2. 비트마스크를 이용한 제한

 

AND 연산 &

NOT 연산 ~ 을 이용합니다.

 

'A' 'B' 'C' 'D' 'E' 'G' 'I' 'M' 'R' 인 문자열을 숫자 65를 빼서 비트로 나타내 보면

 

'A' - 65= 1

'B' - 65 = 2

'C' - 65 = 3

... 이렇게 일반 알파벳 순서로 나타낼 수 있습니다.

 

이를  1 <<  왼쪽연산쉬프트를 통하여 비트로 바꿔준다면

1 << 'A' - 65 = 0000 0001 

1 << 'B' - 65 = 0000 0010

1 << 'C' - 65 = 0000 0100

 

이런식으로 나타낼 수 있을 것입니다.

 

그렇다면 숫자 135519는 무엇일까요?

bitset을 통해 확인해보면

 

32bit에서 A, B, C, D, E, G, I, M, R의 차이값 만큼 왼쪽 쉬프트한 비트임을 알 수 있습니다.

그래서 if( ~t & (1 << (c - 65) ))구문을  통하여 제한하는 문자열을 쉽게 찾을 수 있음을 알게 되었습니다.

 

 

논외로 그리고 이 135519

int tmp =0;
string s = "CAMBRIDGE";
for (char c : s) tmp += (1 << (c - 65));

이렇게 해서 숫자를 찾으면 되겠네요.

 

와 진짜 비트연산 완전 편리하고 좋네요. 잘알아두면 좋을 것 같습니다.


🔔 Code :

이전

#include <iostream>
using namespace std;

int main() {
	char tmp;
	char regulation[9] = {'C', 'A', 'M', 'B', 'R', 'I', 'D', 'G', 'E'};
	while (cin >> tmp) {
		for (int i = 0; i < 9; i++) {
			if (tmp == regulation[i]) {
				tmp = 0;
				break;
			};
		}
		if (tmp != 0) cout << tmp;
	}
}

이후

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

int main() {
	string s;
	int t = 135519;
	cin >> s;
	for (char c : s) if (~t & (1 << (c - 65))) cout << c;
}

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.