알고리즘 기법이라고 볼 수는 없지만 비트마스크 기법을 이용하여 풀 수 있는 문제가 꽤 보여서 알아보기로 하였다.
개념
- 컴퓨터의 최소 연산 단위 bit
- 이진수를 나타내기 위해 0과 1로만 이루어져 있는데, 비트 연산을 통하여 빠르게 해결 할 수 있다.
- 예를 들면 -> bfs나 dfs를 하며 visited를 체크 해줄 때, 크기가 10인 배열을 만드는 경우가 있는데
- 0b0000000000 와 같이 비트마스킹으로 똑같은 표현을 할 수 있다.
- 즉 더 작은 메모리를 사용하여 표현 가능하다.
장점
- 비트 연산은 삽입, 삭제, 조회가 빠르다.
- 코드가 간결해지며
- 정수 표현으로 dp문제 해결 가능
비트 연산
2022.08.10 - [ALGORITHM/알고리즘 알아보기] - 알고리즘 - 부분 집합
알고리즘 - 부분 집합
완전검색 기법으로 모든 부분집합 합 문제를 풀기 위해서는, 우선 집합의 모든 부분집합을 생성한 후에 각 부분집합의 합을 계산해야 한다. 어떻게 계산할 수 있을까? 부분 집합의 생성 부분 집
cheon2308.tistory.com
이전 포스팅에서 알아 보았다.
위의 연산자들을 바탕으로 실제 알고리즘 풀이에 적용해보자.
활용
- 원소 추가
n = 3
print(bin(0b0010 | (1 << n))) # 0b1010
2. 원소 삭제
n = 3
print(bin(0b1010 & ~(1 << n))) # 0b10
3. 원소 조회
- 리턴값이 0이면 없다는 뜻이다.
n = 3
print(bin(0b1010 & (1 << n))) # 0b1000
4. 원소 역전 (토글)
n = 3
print(bin(0b1010 ^ (1 << n))) # 0b10
5. 최소 원소 지우기
a = int('0b100100100', 2)
b = a-1
print(bin(b))
# b = '0b100100011'
# 켜져있는 최하위 bit를 끄고 그 밑의 bit를 전부 켠 것
6. 모든 부분집합 순회하기
a = int('0b1101', 2)
subset = a
while True:
subset = (subset -1) & a
if subset == 0:
break
print(bin(subset))
# 0b1100 -> 1100
# 0b1001 -> 1001
# 0b1000 -> 1000
# 0b101 -> 0101
# 0b100 -> 0100
# 0b1 -> 0001
비트 마스킹을 알고 활용한다면, 파이썬에서도 충분한 메모리와 시간으로 풀 수 있는 문제가 꽤 많은 것 같다.
문제 추천
1. https://www.acmicpc.net/problem/2098
2098번: 외판원 순회
첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 16) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j
www.acmicpc.net
2. https://www.acmicpc.net/problem/1562
1562번: 계단 수
첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.
www.acmicpc.net
'ALGORITHM > 알고리즘 알아보기' 카테고리의 다른 글
[Algorithm] 냅색 알고리즘 (Knapsack Algorithm) (0) | 2023.01.28 |
---|---|
[Algorithm] 위상정렬 (0) | 2023.01.28 |
[Algorithm] Manacher's Algorithm (1) | 2023.01.21 |
[Algorithm] 팰린드롬 판별 알고리즘 (0) | 2023.01.21 |
[Algorithm] 확장 유클리드 알고리즘과 모듈러 곱셈 역원 (0) | 2022.12.31 |