Ssa!
백준 알고리즘 단계별)기초수학 본문
https://www.acmicpc.net/problem/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억 이하의 자연수이다.
|
| 출력 |
첫 번째 줄에 손익분기점 즉 최초로 이익이 발생하는 판매량을 출력한다. 손익분기점이 존재하지 않으면 -1을 출력한다.
|
| 답 | a, b, c=map(int, input().split()) if b >= c: print(-1) else: print(int((a/(c-b))+1)) |
대망의 첫 기초수학 문제이다. 문자열을 하다 이것을 하려니 난이도가 확 올라간다는 것을 느낄 수 있다. 일단 문제의 요점을 파악해보자
A는 고정비용, B는 가변비용, C는 가격이라고 할때 출력의 값에 보면 최초로 이익이 발생하는 판매량을 출력하고 아니면 -1을 출력하라고 한다. 처음보는 사람들은 이게 무슨 소리인가 싶겠지만 먼저 식을 구해야한다.
판매량을 x로 두고 A+Bx => 총비용! 고정비용은 그 이상 변하지 않으니 곱하지 않고 가변비용은 한대를 만들 때 마다 그 비용만큼 비례해서 증가하니 Bx를 한다!
C*x => 총수익! 판매가격과 그 판매량을 곱하면 당연히 총수익이 나온다!
요점에서 말했듯이 최초로 이익이 발생하는 판매량이라고 했다 A+Bx < Cx로 표시할 수 있다. 당연히 총수익이 넘는 순간이 최초의 수익이 발생하는 시점이다! 식으로 표현하면
x끼리 모아두어 A < (Cx - Bx) 로 표시하고 x를 밖으로 빼준다 A < x(C - B)로 표시할 수 있다. 그리고 A / (C-B) < x 로 최종적인 수식이 완성되며 이것을 활용하여 계산할 수 있다.
if문을 보면 b >=c로 표시되어 있는데 가변비용보다 판매비용이 더 낮으면 적자가 발생하니 . . . 조건문을 세워주고 -1을 표시하게 한다. 또한 a/(c-b)+1에서 1이 왜 더해졌지?? 라고 궁금할텐데 문제에서 요구하는 출력값이 정수로 표시가 되어
만약 7.4 이런 식과 같이 소수점으로 표시가 되면 답이 되지 않는다. 그래서 int로 정수로 만들어 주어 +1을 해준다. 물론 올림해주는 함수를 쓰면 +1은 안해도 괜찮다!
https://www.acmicpc.net/problem/2292
| 문제 |
위의 그림과 같이 육각형으로 이루어진 벌집이 있다. 그림에서 보는 바와 같이 중앙의 방 1부터 시작해서 이웃하는 방에 돌아가면서 1씩 증가하는 번호를 주소로 매길 수 있다. 숫자 N이 주어졌을 때, 벌집의 중앙 1에서 N번 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나가는지(시작과 끝을 포함하여)를 계산하는 프로그램을 작성하시오. 예를 들면, 13까지는 3개, 58까지는 5개를 지난다.
|
| 입력 |
첫째 줄에 N(1 ≤ N ≤ 1,000,000,000)이 주어진다.
|
| 출력 |
입력으로 주어진 방까지 최소 개수의 방을 지나서 갈 때 몇 개의 방을 지나는지 출력한다.
|
| 답 | n = int(input()) num = 1 cnt = 1 while n > num: num += 6 *cnt cnt += 1 print(cnt) |
두번 째 문제이다 이것도 처음 차례대로 푸는 사람에게는 어려울 수 있다. 일단 문제의 요점을 찾아보자!
짧게 말해 최소거리를 구하는 문제이다! 이런 문제는 대게 규칙이라는 것이 있다. 종이에 직접 1부터 62까지 표시해본 결과 한 둘레 씩 감쌀 때 마다 6씩 늘어나는 형태를 볼 수 있다. 이런 것은 연속해서 더하는 것이니 반복문을 돌려야한다!
최소 개수를 카운트 하기 위해서 cnt(count)과 num(number)이라는 변수를 둔다. 그런데 왜 처음부터 1로 시작하는가? 라는 의문이 생길 수 있다. 그 이유는 1번방에 있어도 1을 count한다! num이라는 숫자로 한둘레씩 돌 때마다 cnt와 6을 곱하여 더해준다! 그러면 1곂은 1이고 2곂 째에서 7번까지 있으니 6(6*1)+1(1곂)을 해준다! 3곂 째에서는 8번부터 19번까지 있으니 총 갯수는 12개니 12(6*2)+ 7(2곂) 이런식으로 곂곂이 계산해준다
while 문이 만족할 할 경우 벗어나 최단거리를 카운팅 해주는 cnt를 출력해준다!
https://www.acmicpc.net/problem/2869
| 문제 | 땅 위에 달팽이가 있다. 이 달팽이는 높이가 V미터인 나무 막대를 올라갈 것이다. 달팽이는 낮에 A미터 올라갈 수 있다. 하지만, 밤에 잠을 자는 동안 B미터 미끄러진다. 또, 정상에 올라간 후에는 미끄러지지 않는다. 달팽이가 나무 막대를 모두 올라가려면, 며칠이 걸리는지 구하는 프로그램을 작성하시오. |
| 입력 |
첫째 줄에 세 정수 A, B, V가 공백으로 구분되어서 주어진다. (1 ≤ B < A ≤ V ≤ 1,000,000,000)
|
| 출력 |
첫째 줄에 달팽이가 나무 막대를 모두 올라가는데 며칠이 걸리는지 출력한다.
|
| 답 | a, b, v=map(int, input().split()) x = (v - b) / (a - b) if x == int(x): print(int(x)) else: print(int(x)+1) |
내가 쓴 코드를 보자면 . . .분명 로직은 맞게 짰다 근데 왜 틀렸나??? 이 문제의 조건에는 시간제한이 있다. 그것을 생각하면서 짜야한다. 일단 답에 대한 로직을 하나씩 적어보자!
a, b, v = map(int, input().split())
line = 0
cnt = 0
while True:
line += a
if line >= v:
cnt += 1
break
line -= b
cnt += 1
print(cnt)
일단 문제의 요점을 찾아본다. 달팽이가 낮에는 a만큼 올라갔다 밤에는 b만큼 내려간다 그리고 도착지는 v로 표시한다.
거리도달까지 걸리는 일수를 적는것이다!
일단 걸리는 일수를 x로 두자! 수식을 정리하자면 (a-b)x + b = v로 확인할 수 있다 천천히 알아보자면
(a-b)는 달팽이가 올라갔다 내려갔다하는 것을 수식으로 표현한것이다.x는 걸리는 일수를 잰것으로 낮과 밤을 지나고 나면 하루가 걸리는 것이니 올라갔다 내려갔다 하면서 비례하며 하루가 지나가는 것이다. (a-b)x로 표시할 수 있으며 +b는 무엇이냐 생각할 수 있다! v만큼 도달하게 되면 (a-b)에서 올라간 경우만 측정을 하니 내려오는 경우는 +b로 없애주어야하고 목적지 v에 도착하니 저런식으로 표현했다.
x에 관해서 풀어보자면 (a-b)x = v - b이며 x = (v - b) / (a- b)로 확인할 수 있다. 일단 이 값을 x라는 변수에 저장을 해두고
조건식이 두가지로 나뉜다. 다 도착했는데 왜 조건식이 생기냐??라는 의문점이 있다. 출력에 대한 답이 정수로 표현되기에 나누기를 하면 7.4와 같이 소수점이 출력되어 나온다.그러므로 나눠떨어질 우와 아닌경우를 나눠 아닌 경우에는 정수로 바꿔주어 +1을 해준다 물론 이것도 올림함수를 해주면 +1을 빼줘도 된다!
https://www.acmicpc.net/problem/10250
| 문제 | ACM 호텔 매니저 지우는 손님이 도착하는 대로 빈 방을 배정하고 있다. 고객 설문조사에 따르면 손님들은 호텔 정문으로부터 걸어서 가장 짧은 거리에 있는 방을 선호한다고 한다. 여러분은 지우를 도와 줄 프로그램을 작성하고자 한다. 즉 설문조사 결과 대로 호텔 정문으로부터 걷는 거리가 가장 짧도록 방을 배정하는 프로그램을 작성하고자 한다. 문제를 단순화하기 위해서 호텔은 직사각형 모양이라고 가정하자. 각 층에 W 개의 방이 있는 H 층 건물이라고 가정하자 (1 ≤ H, W ≤ 99). 그리고 엘리베이터는 가장 왼쪽에 있다고 가정하자(그림 1 참고). 이런 형태의 호텔을 H × W 형태 호텔이라고 부른다. 호텔 정문은 일층 엘리베이터 바로 앞에 있는데, 정문에서 엘리베이터까지의 거리는 무시한다. 또 모든 인접한 두 방 사이의 거리는 같은 거리(거리 1)라고 가정하고 호텔의 정면 쪽에만 방이 있다고 가정한다. 그림 1. H = 6 이고 W = 12 인 H × W 호텔을 간략하게 나타낸 그림 방 번호는 YXX 나 YYXX 형태인데 여기서 Y 나 YY 는 층 수를 나타내고 XX 는 엘리베이터에서부터 세었을 때의 번호를 나타낸다. 즉, 그림 1 에서 빗금으로 표시한 방은 305 호가 된다. 손님은 엘리베이터를 타고 이동하는 거리는 신경 쓰지 않는다. 다만 걷는 거리가 같을 때에는 아래층의 방을 더 선호한다. 예를 들면 102 호 방보다는 301 호 방을 더 선호하는데, 102 호는 거리 2 만큼 걸어야 하지만 301 호는 거리 1 만큼만 걸으면 되기 때문이다. 같은 이유로 102 호보다 2101 호를 더 선호한다. 여러분이 작성할 프로그램은 초기에 모든 방이 비어있다고 가정하에 이 정책에 따라 N 번째로 도착한 손님에게 배정될 방 번호를 계산하는 프로그램이다. 첫 번째 손님은 101 호, 두 번째 손님은 201 호 등과 같이 배정한다. 그림 1 의 경우를 예로 들면, H = 6이므로 10 번째 손님은 402 호에 배정해야 한다. |
| 입력 |
프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T 는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수를 포함하고 있으며 각각 호텔의 층 수, 각 층의 방 수, 몇 번째 손님인지를 나타낸다(1 ≤ H, W ≤ 99, 1 ≤ N ≤ H × W).
|
| 출력 |
프로그램은 표준 출력에 출력한다. 각 테스트 데이터마다 정확히 한 행을 출력하는데, 내용은 N 번째 손님에게 배정되어야 하는 방 번호를 출력한다.
|
| 답 | t = int(input()) for _ in range(t): h, w, n = map(int, input().split()) yy = 1 # 층수 xx = 1 # 호수 while n > h: n -= h xx += 1 yy = n print(yy*100+xx) |
ACM호텔. . . 문제가 너무 길어 거부감이 들 수 있다. 그치만 인내심을 갖고 읽어보자!!
문제에 대한 요점을 확인해보면 yy는 층수를 나타내고 xx는 호수를 나타낸다. 변수 h,w,n을 받아 h를 기준으로 101, 201, 301 . ..h까지 올라간 다음 102, 202, . . . .이렇게 일의 자리가 바뀌어 다시 h까지 올라간다. 이것을 이용하여 몇번째의 손님이 배정받아야하는 방 번호를 알아내는 것이다. 정말...이거 로직 어떻게 짜야하는지 너무 어렵다 .
일단 for문으로 케이스마다 입력값을 받도록 한다. 그리고 h는 높이 w는 길이 n은 몇 번째 손님인지를 나타낸다.
위의 문제에서 변수를 yy는 층수로 xx는 호수로 설정한다. 1로 설정한 이유는?? 이라고 물어보면 첫 시작이 101호부터 시작하기에 1부터 시작한다. 그리고 while문의 조건을 보면 n>h로 되어 있는 것을 볼 수 있는데 h는 6이라고 생각하고 n 은 10이라고 생각하자! 일단 10번째에 있는 손님은 101 ~ 601호는 다 제외처리된다. 그리고 그 손님이 있을 자리는 402호라는 것을 볼 수 있다. 그러므로 아까 제외시킨 다는 것 처럼 -h를 해준다 그리고 반복문을 돌 때마다 xx변수인 호수를 더해준다. 만약 n이 5이면 while문을 통과하지 않고 yy에 대입되어 나온다.
그리고 yy를 100곱해주고 xx를 표시해준다!

https://www.acmicpc.net/problem/2775
| 문제 | 평소 반상회에 참석하는 것을 좋아하는 주희는 이번 기회에 부녀회장이 되고 싶어 각 층의 사람들을 불러 모아 반상회를 주최하려고 한다. 이 아파트에 거주를 하려면 조건이 있는데, “a층의 b호에 살려면 자신의 아래(a-1)층의 1호부터 b호까지 사람들의 수의 합만큼 사람들을 데려와 살아야 한다” 는 계약 조항을 꼭 지키고 들어와야 한다. 아파트에 비어있는 집은 없고 모든 거주민들이 이 계약 조건을 지키고 왔다고 가정했을 때, 주어지는 양의 정수 k와 n에 대해 k층에 n호에는 몇 명이 살고 있는지 출력하라. 단, 아파트에는 0층부터 있고 각층에는 1호부터 있으며, 0층의 i호에는 i명이 산다. |
| 입력 |
첫 번째 줄에 Test case의 수 T가 주어진다. 그리고 각각의 케이스마다 입력으로 첫 번째 줄에 정수 k, 두 번째 줄에 정수 n이 주어진다
|
| 출력 |
각각의 Test case에 대해서 해당 집에 거주민 수를 출력하라.
|
| 답 | t = int(input()) for _ in range(t): floor = int(input()) # 층 num = int(input()) # 호 f0 = [x for x in range(1, num+1)] # 0층 리스트 for k in range(floor): # 층 수 만큼 반복 for i in range(1, num): # 1 ~ n-1까지 (인덱스로 사용) f0[i] += f0[i-1] # 층별 각 호실의 사람 수를 변경 print(f0[-1]) # 가장 마지막 수 출력 |
이번에 문제들은 하나같이 다 어려운 것 같다. . . .이것 또한 문제의 요점부터 살펴보자!!
a층의 b호에 사려면 자신의 아래 (a-1)층의 1호부터 b호까지 사람들의 수의 합만큼 사람들을 데려와 살아야한다. 라는 것이 가장 중요하다 0층에는 1호부터 1명씩 있다 T라는 케이스를 주어지고 k(층), n(호)라고 생각해야한다.
먼저 t의 입력값을 받아 케이스별로 나눠야하니 for문을 반복시킨다. 그리고 (층) floor과 (호) num을 입력값을 받아온다. 그리고 0층에 리스트 축약식을 사용하여 1에서부터 num+1까지 리스트에 담는다. 층수안에 호수를 반목문 돌려준다. 그런데 호수 1 ~ num까지 하는 의문점이 든다! 왜 num+1까지 아닐까? 왜냐하면 밑에 리스트를 비교하고 저장해주기 위해서 num을 설정했다.

이런식으로 비교하여 숫자를 새롭게 저장하고 기존에 있던 리스트는 초기화를 시킨다. 그리고 호 수에 반복문에 벗어나 층 수의 반복문을 돌리고 또 저장...초기화를 원하는 목표만큼 돌린다. 그리고 리스트의 마지막을 표현하기 위해서 print(f0[-1]) 쓴다!
https://www.acmicpc.net/problem/2839
| 문제 | 상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그램 봉지와 5킬로그램 봉지가 있다. 상근이는 귀찮기 때문에, 최대한 적은 봉지를 들고 가려고 한다. 예를 들어, 18킬로그램 설탕을 배달해야 할 때, 3킬로그램 봉지 6개를 가져가도 되지만, 5킬로그램 3개와 3킬로그램 1개를 배달하면, 더 적은 개수의 봉지를 배달할 수 있다. 상근이가 설탕을 정확하게 N킬로그램 배달해야 할 때, 봉지 몇 개를 가져가면 되는지 그 수를 구하는 프로그램을 작성하시오. |
| 입력 |
첫째 줄에 N이 주어진다. (3 ≤ N ≤ 5000)
|
| 출력 |
상근이가 배달하는 봉지의 최소 개수를 출력한다. 만약, 정확하게 N킬로그램을 만들 수 없다면 -1을 출력한다.
|
| 답 |
n = int(input())
봉지 = 0
while True:
if (n% 5) == 0:
봉지 = 봉지 + (n//5)
print(봉지)
break
n= n-3
봉지 += 1
if n< 0:
print("-1")
break
|
그나마 마지막 문제는 로직 이해하기가 쉬워서 쉽게 풀렸다!
문제를 분석하자면! n kg이 있다고 하면 3kg 과 5kg으로 나눠 제일 적게 들고 갈 수 있는 방법을 찾는 것이다!
5kg 먼저 가져가고 나머지를 3kg로 나누는게 가장 적게 배달하는 방식이다!
n에 입력값을 받고 box로 배달할 봉지를 선언한다. while문으로 반복을 돌린다! if 문을 보면 먼저 n이 5로 빠져야 하니까 봉지에 n 나누기 5를 하여 몫 값을 봉지에 담는다. 그리고 출력하고 탈출한다! 그리고 만약에 5로도 나눠지지 않는 경우에는 3을 빼주고 봉지를 한개 올려준다 그런식으로 while문을 계속 돌린다. 그런데! 그런식으로 하다가 n값이 음수가 되어버리는 경우는 -1을 출력하고 탈출한다! -1은 예제를 보면 조건식을 생각할 수 있다!
느낀점
분수문제도 있었는데 도저히 해설을 봐도 이해가 안되어서 문제를 버렸다. 버렸다기 보다는 나중에 보면 이해할 수 있겠지라는 마음으로 보관을 해둔다! 그리고 이번 기초수학 파트에서 사고력을 요구한다는 것을 크게 느꼈다. 진짜 풀면서 내가 엄청 멍청한 것인가를 자괴감도 들었다. 그치만 튜터님께 물어봤을 때 처음봤으니까 어려운 것이라고 천천히 하라고 하셔서 마음이 안정이되면서 감정소비할 시간보다는 지금의 일을 더 열심히 하자는 마음을 먹었다!
'CS > 알고리즘' 카테고리의 다른 글
| 이것이 코딩테스트다! 수 자료형 (0) | 2022.09.15 |
|---|---|
| 이것이 코딩테스트다! 기초 개념 (0) | 2022.09.15 |
| 백준 알고리즘 단계별)문자열 (1) | 2022.09.13 |
| 백준 알고리즘 단계별)함수 (0) | 2022.09.08 |
| 백준 알고리즘 단계별)1차원 배열 (0) | 2022.09.06 |