https://www.acmicpc.net/problem/1033
1033번: 칵테일
august14는 세상에서 가장 맛있는 칵테일이다. 이 칵테일을 만드는 정확한 방법은 아직 세상에 공개되지 않았지만, 들어가는 재료 N개는 공개되어 있다. 경근이는 인터넷 검색을 통해서 재료 쌍 N
www.acmicpc.net
백준 - 칵테일 (1033번)
난이도 : Gold 2
알고리즘&자료구조 : Mathematics (수학)
★ 핵심 Idea ★
최소공배수(LCM)와 최대공약수(GCD)를 잘 활용해서 풀 수 있다.
< 전체 코드 >
import sys
input = sys.stdin.readline
def gcd(p, q):
while q:
p, q = q, p%q
return p
def lcm(p, q):
return (p // gcd(p, q)) * q
def get_gcded(p, q):
x = gcd(p, q)
return p//x, q//x
def get_lcmed(p, q):
x = lcm(p, q)
return x//p, x//q
def multi(x, v, qnt, grp):
for xx in grp[x]:
qnt[xx] *= v
def combine(a, b, grp):
tmp = grp[a] + grp[b]
for x in tmp:
grp[x] = tmp
class Portions():
def __init__(self, N):
qnt = [1] * N
grp = [[i] for i in range(N)]
for _ in range(N-1):
a, b, p, q = map(int, input().split())
p, q = get_gcded(p, q)
ma, mb = get_lcmed(qnt[a], qnt[b])
ma, mb = get_gcded(ma*p, mb*q)
multi(a, ma, qnt, grp)
multi(b, mb, qnt, grp)
combine(a, b, grp)
self.qunatites = qnt
if __name__ == '__main__':
portions = Portions(int(input()))
print(*portions.qunatites)
① 초기화
값이 모두 1로 초기화 된, 길이 N의 배열 "qnt"를 생성한다.
"qnt"는 각 index에 해당하는 재료의 현재 질량이다.
각 index에 해당 index를 원소로 갖는 배열로 구성된, 이차원 배열 "grp"을 생성한다.
이후에 재료 간 비율이 주어지면서, 서로 간의 관계가 정의된 재료들은 하나의 배열로 합쳐지게 된다.
qnt = [1] * N
grp = [[i] for i in range(N)]
② 최소공배수, 최대공약수 등을 계산해주는 함수를 정의한다.
def gcd(p, q):
while q:
p, q = q, p%q
return p
def lcm(p, q):
return (p // gcd(p, q)) * q
def get_gcded(p, q):
x = gcd(p, q)
return p//x, q//x
def get_lcmed(p, q):
x = lcm(p, q)
return x//p, x//q
③ N-1 개의 주어진 각 입력에 대해서,
p와 q를 서로의 최대공약수로 나눠서 서로소로 만들어준다.
p, q = get_gcded(p, q)
또한 현재 각 재료의 질량인 qnt[a]와 qnt[b]의 최소공배수를 구하고,
qnt[a]와 qnt[b]를 최소공배수로 만들기 위해 곱해야 하는 값을 구한다.
ma, mb = get_lcmed(qnt[a], qnt[b])
위에서 계산한 값들을 아래에서 곱해주면
( qnt[a] * ma * p ) : ( qnt[b] * mb * q ) = p : q 가 되는데, [ (qnt[a] * ma) = (qnt[b] * mb) 이므로 ]
( ma * a ) 와 ( mb * b ) 가 서로소가 아닐 수 있으므로
둘을 서로소로 만들어준다.
ma, mb = get_gcded(ma*p, mb*q)
a 와 b 가 속한 각 그룹에 각각 ma 와 mb 를 곱해준다.
def multi(x, v, qnt, grp):
for xx in grp[x]:
qnt[xx] *= v
multi(a, ma, qnt, grp)
multi(b, mb, qnt, grp)
그룹 a 와 b 를 합쳐준다.
def combine(a, b, grp):
tmp = grp[a] + grp[b]
for x in tmp:
grp[x] = tmp
combine(a, b, grp)
④ 최종 결과 "quantites"를 출력한다.
print(*portions.qunatites)
'Algorithm' 카테고리의 다른 글
집으로 (1069번) - 백준 (BOJ) (0) | 2023.08.25 |
---|---|
창업 (16890번) - 백준 (BOJ) (0) | 2023.08.23 |
깊콘이 넘쳐흘러 (17420번) - 백준 (BOJ) (0) | 2023.08.19 |
행렬과 연산 (118670번) - 프로그래머스 (Programmers) (0) | 2023.08.18 |
가스관 (2931번) - 백준 (BOJ) (0) | 2023.08.15 |