Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 비트집합
- 파이썬
- 데이터엔지니어
- IDA*
- zshrc
- boj
- 윈도우클린설치
- 대학생알고리즘특강
- hmg소프티어부트캠프
- 그리디알고리즘
- code golf
- 소프티어
- 도커
- ucpc
- 소프티어부트캠프
- 에라토스테네스의채
- 알고리즘특강
- spaghetti code
- open(0)
- 우분투22.04
- Short Coding
- 현대자동차
- 표준입력
- 실전sql퀵스타트
- 피보나치수
- 현대자동차그룹
- Python
- 백준
- 데이터엔지니어링
- docker
Archives
- Today
- Total
Neo Ground
[백준 | Python] #9363 - 큰 나눗셈 본문
문제
두 수 $A$, $B$의 인수들 $A_1, A_2, ..., A_n$과 $B_1, B_2, ..., B_n$이 주어진다. 주어진 인수를 통해 $\frac{A}{B}$를 기약분수 형태로 나타내어 출력하여라.
아이디어
각 인수의 최댓값은 100만이다. 100만까지의 소수를 미리 구해놓는 것이 좋을 것 같다. (총 78498개)
인수들의 개수는 최대 22만개이다. 단순히 이들을 모두 곱한다면 당연히 연산 가능한 수를 벗어나므로 인수들을 모두 소인수분해하여 두 수의 소인수의 개수를 각각 세서 A와 B의 소인수 리스트에 저장하는 것이 좋을 것 같다.
100만까지의 수 22만개를 얼마나 빠르게 소인수분해 하냐가 관건일 것 같다.
구현
- 100만까지의 소수를 구하며 각 수의 소인수를 저장한다.
factors 리스트에서 인덱스와 그 인덱스의 소인수의 값이 같다면 그 인덱스는 소수이다.
완전히 소인수분해 하는 것이 아닌 약수 중 소수인 것을 찾는 과정이다. - 딕셔너리 변수
power
를 선언한다.power
는 A와 B의 소인수를 key로 하여 그 거듭제곱 값을 카운트 한다. - A와 B의 인수들에 대해 1에서 구한 소인수를 이용해 빠르게 소인수분해 하며
power
에 저장한다.
A에서는 거듭제곱의 카운트를 증가시키고 B에서는 감소시킨다. power
에 저장된 소인수와 그 거듭제곱 값을 이용해 분자와 분모를 분리하여 계산한다.
코드
factors = [[] for _ in range(1000001)]
def init_factors():
for i in range(2,1000001):
if factors[i]: continue # not prime
factors[i].append(i)
multi = i*2
while multi <= 1000000:
factors[multi].append(i)
multi += i
def solve(a,b):
power = dict()
for factor in a:
for prime in factors[factor]:
if not prime in power: power[prime] = 0
while factor % prime == 0:
power[prime] += 1
factor //= prime
for factor in b:
for prime in factors[factor]:
if not prime in power: power[prime] = 0
while factor % prime == 0:
power[prime] -= 1
factor //= prime
numerator = 1
denominator = 1
for prime in power:
if power[prime] > 0:
numerator *= prime ** power[prime]
else:
denominator *= prime ** -power[prime]
return numerator, denominator
init_factors()
for t in range(int(input())):
input() # n,m is useless
a = list(map(int, input().split()))
b = list(map(int, input().split()))
numerator, denominator = solve(a,b)
print("Case #%d:" %(t+1), numerator, "/", denominator)
후기
효율적인 코드를 찾는다고 머리 좀 썼다. 12초의 쓰레기 풀이는 덤.
'Problem Solving' 카테고리의 다른 글
[백준 | Python] #11444 - 피보나치 수 (cache decorator) (1) | 2023.11.18 |
---|---|
[백준 | Python] #2549 - 루빅의 사각형 (IDA* 알고리즘) (0) | 2023.08.28 |
백준 파이썬 숏코딩 팁 (Python Code Golf) (0) | 2023.08.26 |
[백준 | Python] #11967 - 불켜기 (0) | 2023.07.26 |
[백준 | Python] #16209 - 수열 섞기 (0) | 2023.07.22 |