본문 바로가기

Algorithm

비트마스크

비트마스크란

정수로 집합을 나타내는 방법이다.

포함이 되어있을 땐 1로 포함 되어있지 않을 땐 0으로 나타낸다.

570 같은 경우엔 2진수로 표현하면 1000111010(2)이다.

인덱스로 나타내면

  9   8   7   6   5   4   3   2    1    0
  1   0   0   0   1   1   1   0   1   0

570 = {9, 5, 4, 3, 1}을 포함하고 있는 집합이라고 할 수 있다.

길이가 N인 이진수는 0~N-1까지의 부분집합을 나타낼 수 있다.

1부터 ~ N까지의 부분집합을 나타내고 싶다면

add, remove, check, toggle을 할때 어떤 수 X를 -1 해주도록 하자.

 

* 어떤 수X가 집합에 포함되어 있는지를 검사할 때(check)

N & (1<<X)

1은 이진수로 1이다.

X가 1일 때

1<<X는 10이 된다.

N이 570일때 &연산을 하면

1000111010

             10

--------------&

              10

10진수로 바꾸면 2로 1이상이다.

if((570 & (1 << 1)) > 0)은 true로 570에 1이 포함되어 있다는 뜻이 된다.

 

비트마스크를 사용하는 이유는

어떤 집합을 배열의 인덱스로 표현할 수 있기 때문

이다.

상태 다이나믹에서도 자주 사용되며

완전탐색을 할 때도 모든 경우를 살펴볼 때 재귀호출 없이 for문 하나만으로도

모든 경우를 살펴볼 수 있기 때문이다.

 

* 어떤 수X를 집합에 추가할 때(add)

위와 똑같은 방식으로 비트연산자인 ' | ' 를 사용하면 된다.

N = N | (1<<X)

 

* 어떤 수X를 집합에서 제거할 때(remove)

위와 똑같은 방식으로 비트연산자인 ' & '과 '~' 을 사용하면 된다.

N = N & ~(1<<X)

 

* 어떤수 x가 있으면 x를 제거하고, 없으면 x를 추가한다(toggle)

비트연산자인 ' ^ ' 을 사용하면 된다. (XOR)

N = N ^ (1<<X)

 

* 전체집합

1부터 N까지의 전체 집합이 얻고싶다면

(1<<N) -1

만약 어떤 수 X를 -1하지않고 0~N-1의 부분집합을 사용하고 있다면

(1<<N+1) -1이 된다.

 

* 공집합으로 만들고 싶다면

0

 

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

 

11723번: 집합

첫째 줄에 수행해야 하는 연산의 수 M (1 ≤ M ≤ 3,000,000)이 주어진다. 둘째 줄부터 M개의 줄에 수행해야 하는 연산이 한 줄에 하나씩 주어진다.

www.acmicpc.net

이 문제를 통해 비트마스크를 복습하도록 하자.

'Algorithm' 카테고리의 다른 글

백준 10974 모든 순열 Java  (2) 2019.05.28
백준 10972 이전 순열 & 10973 다음 순열 Java  (0) 2019.05.28
백준 1561 놀이공원 Java  (0) 2019.05.27
백준 1939 중량제한 Java  (0) 2019.05.24
백준 2110 공유기 설치 Java  (0) 2019.05.24