| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- c#기초문법
- c#문제
- 유니티서바이벌게임만들기
- 바킹독알고리즘
- unity3d게임만들기
- unity게임
- c#
- 유니티게임만들기
- C#문법
- 백준코테
- 유니티공부
- unity게임만들기
- c#코테
- unity3d
- unity3dservival
- 백준 구현문제
- 유니티3dui
- 티스토리챌린지
- 오블완
- c#프로그래머스기초문법
- 백준코딩테스트
- c# c#프로그래머스
- c#기본문법
- 백준 C++
- Unity
- 백준
- 백준 c++ 공부
- c#코딩기초트레이닝
- 바킹독
- 유니티
- Today
- Total
나 개발자 진짜 되냐?
백준 C++ 11723번 집합 ( 비트마스크 ) 본문

요즘 독서 중인데
진짜 그.. 뭐랄까 심신에 위안을 받는달까..
책이랑 예전엔 조금 거리가 있었는데
요즘은.. 힐링도서를 종종 찾아서 읽는다.
마음이 따뜻해지는 느낌이다.
다음에는 철학책을 좀 읽어보고 싶다 ㅎ

집합..?
흠.. 그 내 경험적 지식(?)으로는...ㅋㅋㅋㅋ
막 스택 덱 이런 거에 나오던 건데..
집합..?! 은 처음이다.
약간 배열로 푸는 건가?
집합 s라니까..
근데 연산의 수가.. 3백만 개다..ㄷ 흠
그러면 for문을 300백만 번.. 흠..
ㅋㅋ
일단 풀었다.
배열로


자잔!
하지만 제씨는 나에게 이거 말고 더 쉬운 게 있다고 속삭였다.
비트마스킹..?!
비트마스킹
이진수의 각 bit를 플래그 ( 0 또는 1 )로 사용하여
정수 하나로 여러 개의 상태정보를 효율적으로 관리하고 조작하는 기법
비트 단위 연산은 총 4개
AND ( & ) 두 비트가 1일 때만 1
OR ( | ) 두 비트가 둘 중 하나만 1 이어도 1
XOR ( ^ ) 두 값이 다르면 1 같으면 0
NOT( ~ ) 0은 1로 1은 0으로
비트마스킹은 32개의 0과 1을 담고 있기 때문에
굳이 배열을 21개 만들지 않아도!
이 숫자 안에 있는 0과 1을 사용한다...라고 했다.....
그래서...
int S= 0로 정해두고.
S에서 비트연산자를 사용하는 것..
1. add
add는 추가라서 0이 1이 되어야 하니까
겹칠 수 있는 OR이 와야 한다.
S |= ( 1 << x )
그리고 OR이 와주어야
다른 애들은 저장이 되는 동시에 x 칸만큼 이동한 것이 추가로 켜지게 된다.

2. remove
사실 이거 add는 조금 쉬웠는데 remove는 좀 어려웠다.
왜냐면 결과적으로 무조건 0이 되어야 한다.
그럴 땐
AND와 NOT 이 들어와야 한다.
네..?!!? 어려워요.
자 ( 1 << x ) 는 x 만 켜진 상태이다.
그러면 앞에 ~ 를 넣어서
~ (1 << x ) 는 뭘까?
x 빼고 다 켜진 상태가 된다.
이 상태에서
& 를 해주면 된다.
예시로 01010 { 1,3 } 에서 3을 remove 해보자.
1 << 3일 것이고 그럼 01000이다.
~ 해주면 10111이고
이 식을 기존에 01010이랑 & 해주면
AND는 두 비트가 1일 때만 1이니까
00010만 남는다.
그러면 3은 빠지고 1만 된 모습을 볼 수 있다.!

3. check
이거는 이제 if문만 잘 써주면 될 거 같은데?
...
그냥
if (S == (1<<x)) 해주면 안 되나?
NO
이렇게 해주면
x만 가지고 있냐?라고 해석이 되어서 좋은 방향이 아니라고 한다.
그러면.. 뭐가 있을까?
더 좋은 친구가 있다며 소개해주었다...
이 친구 이름은 &
S에 들어있는 식과 (1<<x) 값을 겹쳐서 보는 것이다.
근데 기존에 있던 식과 x칸 간 식 0001이라면 x칸도 기존칸도 1이 같으면 무조건 1이니까!
if문은 & 로 마무리해 준다.

4. toggle
있으면 없애고 없애면 있게 해 주는 것
사실 이거 이름만 들어도 NOT이긴 한데
그냥.. 위에 식들 고대로 옮겨주면 안 되나?

그냥 x가 있으면 빼주고, 없으면 더해주는 위에서 했던 add / remove 쓰면 된다.
하지만 제씨는 아쉬워했다.
진짜가 따로 있다고....
상태를 뒤집기 위해서 태어난 친구가 있다며..
NOT이 아닌 XOR 을 소개해주었다..
두 값이 다르면 1 같으면 0 이 되는 특징을 가지고 있어서
그냥 S ^= (1 << x ) 만 해줘도 된다.

한 줄로 끝!
5. all
모두 1로 만드는 방법이 뭐가 있을까?
전혀 감을 잡지 못하는 나에게 제씨는
이게 비트마스킹의 꽃이라며.. 알려주었다.
S ( 1 << 21) -1;
만 해주면 된단다.
음? 값은 20개까진데 왜 21을?
21을 1이 가면
21번째 칸만 1인,
0이 뒤에 20개인 친구가 만들어진다.
근데 여기서 -1을 해주면
1이 지워지면서
뒤에 친구들이 다 1로 바뀐다.
제씨는 마치 1000-1은 999라고 설명했다.
그리고 사실
S = ~0
도 있다고 한다.
0을 not 해주니 다 1이 된다는 뜻이다.
대신 주의할 점이 비트는 32개라
20번 이상의 숫자를 물어본다면 1이 나온다.
S=1이 안되려나? 했는데
... 이거는 그냥 1인 거고
S ~0 이랑 다른 거다.

6. empty
그냥 S를 0으로 만들면 된다.

와... 비트마스킹..
진짜 비전공자가 비트마스킹을 이해할 수 있을까?
진짜 머리 아프다...
안 엮이고 싶어.......ㅋㅋㅋㅋ
푸는데 두 시간이나 걸렸다.
정확히 말하면
푸는데 10분
답보고 이해하고 정리하는데 1시간 50분..

고생했습니다..........^^
'C++을 시작해봐요! > 구현문제를 풀어봤어요!' 카테고리의 다른 글
| 백준 C++ 11005번 진법 변환 2 ( reverse, 몫과 나머지 ) (0) | 2026.01.16 |
|---|---|
| 백준 C++ 25305번 커트라인 ( sort, nth_element ) (1) | 2026.01.15 |
| 백준 C++ 2747번 피보나치 수 ( 배열 ) (0) | 2026.01.13 |
| 백준 C++ 2745번 진법 변환 ( 진수는 누적 곱! ) (0) | 2026.01.12 |
| 백준 C++ 25206번 너의 평점은 ( mapping, 실수 출력 형식 ) (1) | 2026.01.09 |
