정말 순수하게 비트 마스크 조작 연습 문제다. 각종 비트 마스크 조작의 Best-Practice들을 배워보자. 사소해 보여도 이런 단위 연산을 정형화해두는게 코드를 짤 때 도움이 많이 된다.
비트 연산 시 비트 연산자들의 연산 우선순위를 반드시 고려해 괄호를 쳐줘야 한다.
- 특정 비트 켜기
bm |= (1 << (v - 1));v번째 비트를 1로 바꾼다. 첫 비트의 인덱스는 1이다.
- 특정 비트 끄기
v번째 비트를 0으로 바꾼다. 첫 비트의 인덱스는 1이다.bm &= ~(1 << (v - 1)); - 특정 비트 상태 확인
v번째 비트값을 확인한다. 첫 비트의 인덱스는 1이다.if (bm & (1 << (v - 1)) { printf("1"); } if ((bm & (1 << (v - 1))) == 0) { printf("0"); } - 특정 비트 상태 반전 ( 0이면 1로 변경, 1이면 0으로 변경 )
v번째 비트를 반전시킨다. 첫 비트의 인덱스는 1이다.bm ^= (1 << (v - 1)); - 모든 비트 켜기
n개의 비트를 가진 비트 마스크의 최대값은 이다.mask = (1 << n) - 1; bm = mask; - 모든 비트 끄기
당연히 모든 비트 마스크의 최소값은 0이다.bm = 0;
코드
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
ios::sync_with_stdio(0); cin.tie(0);
int bm = 0;
const int mask = (1 << 21) - 1;
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
string op;
cin >> op;
int v;
if (op.compare("add") == 0) {
cin >> v; v -= 1;
bm |= (1 << v);
}
else if (op.compare( "remove") == 0) {
cin >> v; v -= 1;
bm &= ~(1 << v);
}
else if (op.compare( "check") == 0) {
cin >> v; v -= 1;
if (bm & (1 << v)) {
printf("1\n");
}
else {
printf("0\n");
}
}
else if (op.compare( "toggle") == 0) {
cin >> v; v -= 1;
bm ^= (1 << v);
}
else if (op.compare( "all") == 0) {
bm = mask;
}
else if (op.compare( "empty") == 0) {
bm = 0;
}
}
}