💻 백준 1094: 막대기
- 문제 링크: https://www.acmicpc.net/problem/1094
- 알고리즘 분류: 비트마스킹
문제 소개 🧐
길이가 64cm인 막대를 잘라서 Xcm 막대를 만드는 문제. 막대를 절반으로 자르는 과정을 반복하며, 남은 막대들의 길이 합이 X가 되도록 할 때, 최종적으로 사용된 막대의 개수를 구해야 한다.
- 핵심 규칙:
- 처음 막대는 64cm.
- 막대들의 합이 X보다 크면, 가장 짧은 막대를 절반으로 자른다.
- 자른 막대의 절반 중 하나를 버려도 합이 X 이상이면, 버린다.
입력 📝
- X (64 이하의 자연수)
출력 📤
- Xcm를 만드는데 필요한 막대의 개수
제한 ❌
- 2초, 128MB
첫 번째 시도: 시뮬레이션 👊
Idea
문제에 주어진 과정을 그대로 따라가며 구현했다. 64부터 시작해서 계속 절반으로 나누고, 현재 가진 막대들의 합과 X를 비교하며 막대를 추가하거나 버리는 방식
Code
import sys
x = int(sys.stdin.readline().rstrip())
cnt = 0
cur_len = 64
while x>0:
if x - cur_len == 0:
cnt += 1
x -= cur_len
print(cnt)
elif x -cur_len < 0:
pass
else:
x -= cur_len
cnt += 1
cur_len = cur_len >> 1
Result
- 성공! ✅
두 번째 시도: 비트마스킹 ✨
Idea
문제의 막대 길이(64, 32, 16, …)가 2의 거듭제곱 형태인 것을 보고, X를 2진수로 변환했을 때 1의 개수가 곧 필요한 막대의 개수와 같다는 것을 깨달았다.
Code
import sys
from collections import Counter
x = int(sys.stdin.readline().rstrip())
print(Counter(bin(x)).get('1'))
Result
- 성공! ✅
개선할 부분 🤔
- 2진수와 관련된 문제에서는 비트마스킹을 활용하면 훨씬 간결하고 효율적인 코드를 작성할 수 있다는 점을 기억해야겠다.