문제
지민이는 길이가 64cm인 막대를 가지고 있다. 어느 날, 그는 길이가 Xcm인 막대가 가지고 싶어졌다. 지민이는 원래 가지고 있던 막대를 더 작은 막대로 자른다음에, 풀로 붙여서 길이가 Xcm인 막대를 만들려고 한다.
막대를 자르는 가장 쉬운 방법은 절반으로 자르는 것이다. 지민이는 아래와 같은 과정을 거쳐서 막대를 자르려고 한다.
- 지민이가 가지고 있는 막대의 길이를 모두 더한다. 처음에는 64cm 막대 하나만 가지고 있다. 이때, 합이 X보다 크다면, 아래와 같은 과정을 반복한다.
- 가지고 있는 막대 중 길이가 가장 짧은 것을 절반으로 자른다.
- 만약, 위에서 자른 막대의 절반 중 하나를 버리고 남아있는 막대의 길이의 합이 X보다 크거나 같다면, 위에서 자른 막대의 절반 중 하나를 버린다.
- 이제, 남아있는 모든 막대를 풀로 붙여서 Xcm를 만든다.
X가 주어졌을 때, 위의 과정을 거친다면, 몇 개의 막대를 풀로 붙여서 Xcm를 만들 수 있는지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 X가 주어진다. X는 64보다 작거나 같은 자연수이다.
출력
문제의 과정을 거친다면, 몇 개의 막대를 풀로 붙여서 Xcm를 만들 수 있는지 출력한다.
예제 입력 1
23
예제 출력 1
4
예제 입력 2
32
예제 출력 2
1
예제 입력 3
64
예제 출력 3
1
예제 입력 4
48
예제 출력 4
2
나의 풀이
문제에 쓰여있는 과정대로 코드를 짜주면 되는 문제였다. 필자는 저렇게 하기 위해서 막대기를 담는 배열을 사용하여 pop과 append를 이용해 풀었다. 우선 x가 64가 들어오는 경우에는 1을 출력해주고 그렇지 않은 경우 저 과정을 따랐다. 우선 sticks라는 배열에 64를 넣어주고 각 단계별로 맨 뒤의 원소를 pop하여 2로 나누어준다. 이 나눈 값과 현재 sticks의 모든 원소의 합을 더한 값이 x와 같으면
sticks배열에 들어있는 원소의 수 + 1
이 정답이고 저 값이 x보다 크다면 2로 나눈값 하나를 버리므로 하나만 sticks배열에 append를 해주고 작다면 2번 append를 해주었다. 이렇게 작은 값이 맨 뒤로 들어가지게 되어 다음번 막대기를 pop할때에도 마지막 원소를 꺼낸다면 최솟값을 꺼내게 된다.
코드
# 1094번 막대기
# main
X = int(input())
if X == 64:
print(1)
else:
sticks = [64]
while True:
s = sticks.pop()
sHalf = s // 2
if sum(sticks) + sHalf == X:
print(len(sticks) + 1)
break
elif sum(sticks) + sHalf > X:
sticks.append(sHalf)
else:
for _ in range(2):
sticks.append(sHalf)
'Programming > Algorithm' 카테고리의 다른 글
[백준1074번] Z / Python3 (0) | 2020.04.10 |
---|---|
[백준2631번] 줄세우기 / Python3 (0) | 2020.04.10 |
[백준1476번] 날짜 계산 / Python3 (0) | 2020.04.10 |
[백준10164번] 격자상의 경로 / Python3 (0) | 2020.04.08 |
[백준9507번] Generations of Tribbles / Python3 (0) | 2020.04.08 |