티스토리 뷰
#1712 손익분기점
월드전자는 노트북을 제조하고 판매하는 회사이다. 노트북 판매 대수에 상관없이 매년 임대료, 재산세, 보험료, 급여 등 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억 이하의 자연수이다.
입출력 예제
| 입력 | 출력 |
| 1000 70 170 | 11 |
풀이
A, B, C = map(int,input().split(' '))
if B >= C :
print(-1)
else :
print((A // (C-B)) +1)
A는 고정되어 있으므로 상수, 나머지 B와 C는 생산되는 제품의 개수에 따른 변수로 둔다.
입력값이 21억 이하의 자연수라고 했으니 while을 사용하면 시간초과가 날 것이다. (나처럼 ^-^)
문제를 해결하기 위해서 부등식을 다시 정리해보았다.
A + n * B < n * C
A < n * (C - B)
A / (C - B) < n ------ if 문에서 C-B 값이 음수가 되는 조건은 뺏으므로 부등호 방향은 바뀌지 않는다.
제품을 판매하는 개수는 무조건 정수이므로 ( 1.8개 이런 식으로 팔 순 없으니 ) 좌변의 몫을 구한다.
이 몫 값에 +1을 하는 시점이 바로 이익이 발생하는 시점이다.
#2839 설탕 배달
상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그램 봉지와 5킬로그램 봉지가 있다.
상근이는 귀찮기 때문에, 최대한 적은 봉지를 들고 가려고 한다. 예를 들어, 18킬로그램 설탕을 배달해야 할 때, 3킬로그램 봉지 6개를 가져가도 되지만, 5킬로그램 3개와 3킬로그램 1개를 배달하면, 더 적은 개수의 봉지를 배달할 수 있다.
상근이가 설탕을 정확하게 N킬로그램 배달해야 할 때, 봉지 몇 개를 가져가면 되는지 그 수를 구하는 프로그램을 작성하시오. (단, 정확하게 N킬로그램을 만들 수 없다면 -1을 출력한다.)
입출력 예제
| 입력 | 출력 |
| 18 | 4 |
| 4 | -1 |
| 11 | 3 |
풀이
kg = int(input())
cn = 0
while True:
if (kg % 5 != 0) and (kg > 0):
kg -= 3
cn += 1
else:
break
if kg < 0:
print(-1)
else:
cn += int(kg / 5)
print(cn)
처음에는 인수분해를 생각했지만 복잡해질까봐 그만두었다.
최소값을 구하기 위해서는 5KG 봉지를 최대한 많이 챙겨야 한다는 것이 핵심이다.
따라서, 배달해야 하는 총 KG에서 5로 나누어 떨어질 때까지 3을 빼주면서
count 값을 누적해준다. ( 3KG 봉지가 count된다. )
while문을 빠져나왔다면 KG이 음수인지 먼저 판단한다. 만약 음수라면
3으로도 나누어 떨어지지 않았다는 뜻이므로 -1을 리턴한다.
그렇지 않다면 누적된 count 값 (3KG 봉지 개수) 에 나머지 KG을 5로 나눈 몫을 더해 값을 리턴한다.
#2292 벌집

위의 그림과 같이 육각형으로 이루어진 벌집이 있다. 그림에서 보는 바와 같이 중앙의 방 1부터 시작해서 이웃하는 방에 돌아가면서 1씩 증가하는 번호를 주소로 매길 수 있다.
숫자 N이 주어졌을 때, 벌집의 중앙 1에서 N번 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나가는지(시작과 끝을 포함하여)를 계산하는 프로그램을 작성하시오.
(예를 들면, 13까지는 3개, 58까지는 5개를 지난다.)
입력
첫째 줄에 N(1 ≤ N ≤ 1,000,000,000)이 주어진다.
입출력 예제
| 입력 | 출력 |
| 13 | 3 |
풀이
x = int(input())
n = 1
while 3*(n*(n-1)) + 1 < x:
n += 1
print(n)
문제가 복잡해보여서 그렇지 풀이는 그렇게 어렵지 않다.
규칙을 찾아보고 입력값이 규칙의 몇 번째 항에 있는지 확인하자.
차례대로 첫 번째는 1 하나, 두 번째는 2 ~ 7 까지 여섯개, 세 번째는 8 ~ 19 까지 열두개 ...
즉, n번째 까지의 벌집 갯수는 각 항의 제일 마지막 숫자인 1 7 19 37 61 ... 이 되고 6n씩 늘어난다.
따라서 n번째의 항은, 6n씩 계속해서 더해주는 형태, 계차수열임을 알 수 있다.
1 : 1
7 : 1 + 6 * 1
19 : 1 + 6 * 1 + 6 * 2
따라서, 우리는 계차수열의 공식을 이용해서 다음과 같은 식을 유도해볼 수 있다.
6n * ( n - 1 ) / 2 + 1 = 3n * ( n - 1 ) + 1
n이 증가할 때마다 이동거리도 증가하기 때문에 입력값이 어느 위치에 있는지
while 을 이용해서 n 값을 구해주면 이동거리도 구할 수 있게 된다.
#1193 분수찾기
| 1/1 | 1/2 | 1/3 | 1/4 | 1/5 | … |
| 2/1 | 2/2 | 2/3 | 2/4 | … | … |
| 3/1 | 3/2 | 3/3 | … | … | … |
| 4/1 | 4/2 | … | … | … | … |
| 5/1 | … | … | … | … | … |
| … | … | … | … | … | … |
이와 같이 나열된 분수들을 1/1 -> 1/2 -> 2/1 -> 3/1 -> 2/2 -> … 과 같은 지그재그 순서로 차례대로 1번, 2번, 3번, 4번, 5번, … 분수라고 하자.
X가 주어졌을 때, X번째 분수를 구하는 프로그램을 작성하시오.
입출력 예제
| 입력 | 출력 |
| 14 | 2/4 |
풀이
def SUM(n):
return int((n*(n+1)) / 2)
X = int(input())
n = 1
while SUM(n) < X :
n+=1
if n % 2 != 0:
rem = X - SUM(n-1)
mom = n - rem + 1
print('{}/{}'.format(mom, rem))
else :
mom = X - SUM(n-1)
rem = n - (mom-1)
print('{}/{}'.format(mom, rem))
군수열이다...
몇번째 군에 속하는지 먼저 확인하고, 해당 군에서 어느 위치에 있는지 파악하면 된다.
참고로 홀수 군과 짝수 군일 때의 진행 방향이 틀림에 유의하자. ( 나란놈...... )
우선, SUM 이라는 함수를 생성했는데 몇 군에 속하는지 출력해주는 역할을 한다.
각 군은 친절하게도 1, 2, 3 ... 순서로 증가하기 때문에 어떤 숫자가 들어왔을 때,
저 친구를 이용하면 군을 바로 캐치할 수 있다.
조심할 점은 while 특성상 n 값이 마지막에 더해진 뒤에 빠져나오기 때문에 -1을 해주어야 한다.
그리고 규칙에 맞게 식을 세워주면 된다.
지금보니 마지막에 mom, rem 변수를 반대로 선언한 듯 하다... ( 나란놈.... )
'프로그래밍 > BOJ' 카테고리의 다른 글
| 백준 #10250: AMC 호텔 (0) | 2020.01.17 |
|---|---|
| 백준 #2869: 달팽이는 올라가고싶다 (0) | 2020.01.17 |
| 백준: #단계별로 풀어보기, 문자열 (2) (0) | 2020.01.12 |
| 백준: #단계별로 풀어보기, 문자열 (1) (0) | 2020.01.12 |
| 백준: #단계별로 풀어보기, 함수 (0) | 2020.01.11 |