[백준] [python] 1094

Jinho Lee ·2023년 8월 22일
post-thumbnail

1094 막대기

시간제한: 2초

문제

지민이는 길이가 64cm인 막대를 가지고 있다. 어느 날, 그는 길이가 Xcm인 막대가 가지고 싶어졌다. 지민이는 원래 가지고 있던 막대를 더 작은 막대로 자른다음에, 풀로 붙여서 길이가 Xcm인 막대를 만들려고 한다.

막대를 자르는 가장 쉬운 방법은 절반으로 자르는 것이다. 지민이는 아래와 같은 과정을 거쳐서 막대를 자르려고 한다.

지민이가 가지고 있는 막대의 길이를 모두 더한다. 처음에는 64cm 막대 하나만 가지고 있다. 이때, 합이 X보다 크다면, 아래와 같은 과정을 반복한다.

  1. 가지고 있는 막대 중 길이가 가장 짧은 것을 절반으로 자른다.
  2. 만약, 위에서 자른 막대의 절반 중 하나를 버리고 남아있는 막대의 길이의 합이 X보다 크거나 같다면, 위에서 자른 막대의 절반 중 하나를 버린다.

이제, 남아있는 모든 막대를 풀로 붙여서 Xcm를 만든다.
X가 주어졌을 때, 위의 과정을 거친다면, 몇 개의 막대를 풀로 붙여서 Xcm를 만들 수 있는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 X가 주어진다. X는 64보다 작거나 같은 자연수이다.

출력

문제의 과정을 거친다면, 몇 개의 막대를 풀로 붙여서 Xcm를 만들 수 있는지 출력한다.

예제1

# 입력
23
# 출력
4

예제2

# 입력
32
# 출력
1

예제3

# 입력
64
# 출력
1

예제4

# 입력
48
# 출력
2

풀이 과정

문제 해석

문제에 나온 그대로 구현해서 최종적인 막대의 개수를 구하는 문제이다.

사고 흐름

  1. 문제에 구현해야하는 내용이 명확하게 나와있다.
  2. 과정을 반복한다 라는 말을 보고 반복문을 사용하면 되겠다고 생각했다.
  3. 반복문에서 다룰 변수는 막대의 개수, 제일 작은 막대의 길이, 버린 막대를 제외한 나머지 막대의 길이의 합 이렇게 세 개라고 생각했다.
  4. 문제에 나온대로 구현을 하였다.

코드 작성

X = int(input())

# 초기 막대의 개수
barCnt = 1

# 가장 작은 막대의 길이
smallest = 64

# 버린 막대를 제외한 나머지 막대의 길이의 합
sumOfBarLen = 64

# 막대 길이의 합이 X보다 크지 않을 때까지 반복
while X < sumOfBarLen:
    # 1. 가지고 있는 막대 중 길이가 가장 짧은 것을 절반으로 자른다.
    smallest //= 2

    # 2. 만약, 위에서 자른 막대의 절반 중 하나를 버리고 남아있는 막대의 길이의 합이 
    # X보다 크거나 같다면, 위에서 자른 막대의 절반 중 하나를 버린다.
    if sumOfBarLen - smallest >= X:
        sumOfBarLen -= smallest

    # 막대를 버리지 않았다면 자른 막대를 모두 사용함. 즉, 총 막대의 개수가 +1 증가.
    else:
        barCnt += 1

print(barCnt)

위의 코드는 문제에 나와있는 흐름대로 그대로 구현을 한 것이다. 하지만 답을 도출하는 방법을 좀 더 간소화 할 수 있다. X는 자연수이고, 계속 절반으로 자른 막대를 사용하기 때문에 Xcm 길이의 막대기를 구성하는 막대의 길이는 202^0, 212^1 \dots ~ 252^5, 262^6가 될 수 밖에 없다. 따라서 64를 2로 나누어 가면서 나누어진 수가 X에 비해 작을 경우 카운트를 +1 하는 방식으로도 구현할 수 있다. 정리하자면 202^0, 212^1 \dots ~ 252^5, 262^6 수를 가장 적게 사용해서 X를 만들 때, 사용한 수를 구하는 것이다. 코드는 다음과 같다.

X = int(input())

# 초기 막대의 개수
barCnt = 0

# 더해나가는 막대의 총 길이
barLen = 0

# 가장 작은 막대의 길이
smallest = 64

while barLen != X:
    if X - barLen >= smallest:
        barLen += smallest
        barCnt += 1
    smallest /= 2
print(barCnt)

총평

문제의 흐름대로 읽어가며 코드로 구현한다면 쉽게 풀리는 문제이다.

profile
오류나 오타 지적 환영합니다

0개의 댓글