티스토리 뷰
백준 1094번 막대기
알고리즘 분류: 수학, 비트마스킹, 선형대수학
링크: https://www.acmicpc.net/problem/1094
문제
지민이는 길이가 64cm인 막대를 가지고 있다. 어느 날, 그는 길이가 Xcm인 막대가 가지고 싶어졌다. 지민이는 원래 가지고 있던 막대를 더 작은 막대로 자른다음에, 풀로 붙여서 길이가 Xcm인 막대를 만들려고 한다.
막대를 자르는 가장 쉬운 방법은 절반으로 자르는 것이다. 지민이는 아래와 같은 과정을 거쳐서 막대를 자르려고 한다.
- 지민이가 가지고 있는 막대의 길이를 모두 더한다. 처음에는 64cm 막대 하나만 가지고 있다. 이때, 합이 X보다 크다면, 아래와 같은 과정을 반복한다.
- 가지고 있는 막대 중 길이가 가장 짧은 것을 절반으로 자른다.
- 만약, 위에서 자른 막대의 절반 중 하나를 버리고 남아있는 막대의 길이의 합이 X보다 크거나 같다면, 위에서 자른 막대의 절반 중 하나를 버린다.
- 이제, 남아있는 모든 막대를 풀로 붙여서 Xcm를 만든다.
X가 주어졌을 때, 위의 과정을 거친다면, 몇 개의 막대를 풀로 붙여서 Xcm를 만들 수 있는지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 X가 주어진다. X는 64보다 작거나 같은 자연수이다.
출력
문제의 과정을 거친다면, 몇 개의 막대를 풀로 붙여서 Xcm를 만들 수 있는지 출력한다.
문제 파악
이 문제는 지민이가 Xcm인 막대를 가지고 싶어서 64cm인 막대를 계속 반으로 잘라서
Xcm에 맞춰 길이를 가져다 붙이는데 이 때 몇개의 막대기를 붙여야 만들 수 있냐는 문제이다.
위에 지문의 조건이 길어서 무슨 말인지 이해하는데 방해가 되는데
이를 생각하다보니 쉽게 풀 수 있을것 같아서 약간 그리디 알고리즘처럼 풀었다.
어차피 길이가 64cm인 막대기를 계속 반으로 나눠도 64, 32, 16, 8, 4, 2, 1 까지밖에 나눌 수 없다.
그래서 큰 막대기 부터 Xcm인 막대기와 비교하면서 가져다 붙이면 된다.
코드
# 1094번
x = int(input())
stick = [64, 32, 16, 8, 4, 2, 1]
count = 0
for i in range(len(stick)):
if x >= stick[i]:
count += 1
x -= stick[i]
if x == 0:
break
print(count)
만들 수 있는 막대기의 모든 길이를 처음부터 stick이라는 리스트에 담아둔다.
큰 막대기부터 x와 비교해서 x가 더 크다면 그 막대기를 붙이고 x는 그 막대기의 길이만큼 빼준다.
남은 길이만큼을 다시 나머지 막대기들과 비교해서 x가 0이 될때까지 막대기를 붙인다.
x가 0이되면 반복문을 종료하고 몇개의 막대기를 붙였는지 출력한다.
예를들어 x의 길이가 23cm이라면 x를 만들기 위해선 64cm와 32cm는 너무 큰 막대기일 것이다.
16cm은 23cm보다 작기 때문에 16cm을 붙이고나면 x만큼 되기 위해선 7cm가 남는다.
8cm짜리 막대기는 7cm보다 크기 때문에 안되고 4cm짜리 막대기를 붙여준다.
이제 3cm가 남았기 때문에 2cm와 1cm막대기를 붙여주면
23cm = 16cm + 4cm + 2cm + 1cm로 총 4개의 막대기가 필요한 것이다.
'Python 알고리즘' 카테고리의 다른 글
백준 10610번 파이썬 풀이: 30 (0) | 2020.09.06 |
---|---|
백준 8979번 파이썬 풀이: 올림픽 (0) | 2020.09.06 |
백준 1010번 파이썬 풀이: 다리 놓기 (0) | 2020.09.06 |
백준 1002번 파이썬 풀이: 터렛 (1) | 2020.09.05 |
백준 9020번 파이썬 풀이: 골드바흐의 추측 (2) | 2020.09.05 |