-
Notifications
You must be signed in to change notification settings - Fork 15
/
new-elements-part-2.py
46 lines (40 loc) · 1.46 KB
/
new-elements-part-2.py
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Copyright (c) 2019 kamyu. All rights reserved.
#
# Google Code Jam 2019 Round 2 - Problem C. New Elements: Part 2
# https://codingcompetitions.withgoogle.com/codejam/round/0000000000051679/0000000000146184
#
# Time: O(N^2 * log(max(C, J)))
# Space: O(log(max(C, J)))
#
from fractions import Fraction
def find_min_fraction_with_min_denominator_between(a, b, d=0):
assert(a < b)
assert(d < 9)
if b-int(a) > 1:
return Fraction(int(a)+1, 1)
if a-int(a) == 0:
return int(a) + Fraction(1, int(1/(b-int(a)))+1)
return int(a) + 1/find_min_fraction_with_min_denominator_between(1/(b-int(a)), 1/(a-int(a)), d+1)
def new_elements_part_2():
N = input()
molecules = []
for _ in xrange(N):
molecules.append(map(int, raw_input().strip().split()))
L, U = Fraction(0, 1), Fraction(MAX_C_J, 1)
for b in xrange(1, N):
(Cb, Jb) = molecules[b]
for a in xrange(b):
(Ca, Ja) = molecules[a]
if (Ca < Cb and Ja > Jb):
U = min(U, Fraction(Ca-Cb, Jb-Ja))
elif (Ca > Cb and Ja < Jb):
L = max(L, Fraction(Ca-Cb, Jb-Ja))
elif (Ca >= Cb) and (Ja >= Jb):
return "IMPOSSIBLE"
if L >= U:
return "IMPOSSIBLE"
frac = find_min_fraction_with_min_denominator_between(L, U)
return "{} {}".format(frac.denominator, frac.numerator)
MAX_C_J = 10**9
for case in xrange(input()):
print 'Case #%d: %s' % (case+1, new_elements_part_2())