본문 바로가기

개발일지/TIL

TIL 23-04-23 백준 알고리즘 - 달팽이는 올라가고 싶다

1. 백준 알고리즘 - 달팽이는 올라가고 싶다

 문제점

문제 설명
땅 위에 달팽이가 있다. 이 달팽이는 높이가 V미터인 나무 막대를 올라갈 것이다.

달팽이는 낮에 A미터 올라갈 수 있다. 하지만, 밤에 잠을 자는 동안 B미터 미끄러진다. 
또, 정상에 올라간 후에는 미끄러지지 않는다.

달팽이가 나무 막대를 모두 올라가려면, 며칠이 걸리는지 구하는 프로그램을 작성하시오.

입력
첫째 줄에 세 정수 A, B, V가 공백으로 구분되어서 주어진다. (1 ≤ B < A ≤ V ≤ 1,000,000,000)

출력
첫째 줄에 달팽이가 나무 막대를 모두 올라가는데 며칠이 걸리는지 출력한다.

# 낮에 A미터 상승, 밤에 B미터 하락 정상 등반시 하락X

# A = 올라감, B = 내려감, V= 정상

 

 시도해 본 것들

while문을 통한 방법 시도 

A, B, V = map(int, (input().split()))
current_height = 0
count = 0
while True:
    count += 1
    current_height += A
    if current_height >= V:
        break
    current_height -= B
print(count)

A, B, V = 100, 99, 1000000000 같은 경우 while문이 너무 오래걸림 

 

수식으로 작성하기 

# V - A하고 남은 값을 A-B로 채운다
A, B, V = map(int, (input().split()))
print((V - A)//(A-B) + 1)

V-A = 정상 등반날의 상승, +1은 V-A의 count,  A-B 나머지 날의 상승폭

이렇게 바꿨을 때 // 하는 과정에서 결과값이 1이하일 경우 0으로 바뀌는 문제 발생

 

float으로 만들고 round 시도 

A, B, V = map(int, (input().split()))
print(round(V - A)/(A-B))

round의 작동 구조가 반올림이므로 결과값이 0이 아니면 1로 바꿔야 하는 내 기대와 다른 결과

 

math 사용

import math
# ceil은 올림
# floor은 내림
A, B, V = map(int, (input().split()))
print(math.ceil((V - A)/(A-B)) + 1)

 

 해결 방법

import math

A, B, V = map(int, (input().split()))
print(math.ceil((V - A)/(A-B)) + 1)

 알게 된 점

수식으로 작성했던 경험이 조금씩 쌓이면서 시작을 while문으로 했지만 어렵지 않게 수식으로 바꿀 수 있었다.

알고리즘에서 import를 하면서 문제를 처음 풀었는데 어떤게 필요한지 알고 잘 썼다는 생각이 든다.

1.백준 알고리즘 - 손익분기점

 문제점

문제 설명
월드전자는 노트북을 제조하고 판매하는 회사이다. 
노트북 판매 대수에 상관없이 매년 임대료, 재산세, 보험료, 급여 등 A만원의 고정 비용이 들며, 
한 대의 노트북을 생산하는 데에는 재료비와 인건비 등 총 B만원의 가변 비용이 든다고 한다.

예를 들어 A=1,000, B=70이라고 하자. 이 경우 노트북을 한 대 생산하는 데는 총 1,070만원이 들며,
열 대 생산하는 데는 총 1,700만원이 든다.

노트북 가격이 C만원으로 책정되었다고 한다. 
일반적으로 생산 대수를 늘려 가다 보면 어느 순간 총 수입(판매비용)이 총 비용(=고정비용+가변비용)보다 많아지게 된다. 
최초로 총 수입이 총 비용보다 많아져 이익이 발생하는 지점을 손익분기점(BREAK-EVEN POINT)이라고 한다.

A, B, C가 주어졌을 때, 손익분기점을 구하는 프로그램을 작성하시오.

입력
첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 21억 이하의 자연수이다.

출력
첫 번째 줄에 손익분기점 즉 최초로 이익이 발생하는 판매량을 출력한다. 
손익분기점이 존재하지 않으면 -1을 출력한다.

# 손익 분기점 구하기

# 입력 고정 비용 = A, 가변 비용 = B, 노트북 가격 C

# 출력 손익 분기점이 되는 판매량

# 팔수록 손해보는 경우 -1

 시도해 본 것들

while문으로 시도

A, B, C = map(int, input().split())
count = 0
if B > C:
    print(-1)
else:
    while A > -1:
        count += 1
        A -= (C - B)
    print(count)

if문으로 팔수록 손해가 발생하는 경우 -1 출력

A = 2100000000, B = 9,C = 10인 경우 while문이 너무 오래 걸리는 문제 발생

A, B, C = map(int, input().split())
if B > C:
    print(-1)
else:
    print(A // (C-B)+1)

 고정비용 // (남는 마진)은 고정비용을 상계하고 +1부터 이익이 남음 

제출시 ZeroDivisionError 발생

 

ZeroDivisionError 해결

print(1000//0 + 1)

이 테스트 코드를 통해서 C-B == 0인 경우를 걸러줘야 함을 알아냄. 그리고 C-B == 0인 경우는 고정비용을 영원히 상계할 수 없는 경우이므로 if문 수정 

if B >= C:

 해결 방법

A, B, C = map(int, input().split())
if B >= C:
    print(-1)
else:
    print(A // (C-B)+1)

 알게 된 점

2주 전만해도 코드에 반복문이 있으면 열심히 만든 것 같아서 좋아했는데, 이제는 반복문을 없애면서 뿌듯함을 느낀다.