-
백준 1094 막대기 (비트 개수 세기)Algorithm/BOJ 2021. 6. 3. 15:31728x90
출처: https://www.acmicpc.net/problem/1094
분류: 비트마스킹
접근방식
주어진 문제의 조건을 맹목적으로 따라서 풀 수도 있지만,
조건을 해보면 결국은 주어진 x를 몇 개의 2의 배수를 사용해 만들 수 있느냐 하는 문제입니다.다시 생각해보면 "x를 이진수로 만들었을 때 1이 몇 개냐" 라는 말과 같은 말이라는 걸 알 수 있습니다 :)
따라서 이진수에서 1이 몇 개인지 세는 방법을 알아보겠습니다.
2로 나누기
우선 비트 연산을 하지 않는다면 주어진 수를 x로 나눠가면서 셀 수가 있겠네요.
중학생(?)때 배우는 10진수를 2진수로 바꿀 때 나눠가면서 나머지를 세는 바로 그 방식입니다.while x > 0 { bitCount += x % 2 x /= 2 }
>> 1
2로 나누는 걸 비트연산으로 하려면 오른쪽으로 쉬프트 1 해주면 되겠네요
그 전에 마지막 비트가 켜져있는지 1과 &연산을 통해 확인합니다.while x > 0 { bitCount += x & 1 x >>= 1 }
x & (x-1 )
어떤 수와 그보다 1작은 수를 &연산 하면 마지막 비트를 꺼줄 수 있습니다.
이건 직접 해보면 금방 이해가 가실텐데요,
예를 들어,
4는 이진수로 100 이고 3은 이진수로 011이 됩니다.
4의 마지막 비트를 0으로 바꿔주고 싶네요, 1은 하나뿐이니 연산 결과가 0이 되면 되겠죠?
4와 3을 &연산하면 0이 됩니다.10는 이진수로 1010이고 9는 1001 입니다.
10의 마지막 비트를 꺼주면 2자리 비트가 꺼지고 결과는 1000이 되어야겠네요.
10과 9를 &연산하면 결과는 1000이 됩니다 :)while x > 0 { x &= (x-1) bitCount += 1 }
해결방법
var x = Int(readLine()!)! var bitCount = 0 while x > 0 { // 맨 마지막 비트가 꺼짐 x &= (x-1) bitCount += 1 } print(bitCount)
배운점
비트 연산으로 참 많은 걸 할 수 있다.
신비로운 세계 :(
'Algorithm > BOJ' 카테고리의 다른 글
백준 13335 트럭 (0) 2021.06.04 백준 2250 트리의 높이와 너비 (0) 2021.06.04 백준 2056 작업 (0) 2021.06.03 백준 2169 로봇 조종하기 (0) 2021.06.02 백준 7579 앱 (0) 2021.06.02