Skip to content

Commit 53158b2

Browse files
committed
contest
1 parent 659a8d0 commit 53158b2

4 files changed

+143
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# simple logic
2+
3+
def minOperations(nums: list[int], k: int) -> int:
4+
if any(i < k for i in nums):
5+
return -1
6+
7+
nums.sort()
8+
res = list(set([i for i in nums if i >= k]))
9+
if k in res:
10+
return len(res) - 1
11+
else:
12+
return len(res)
13+
14+
15+
print(minOperations(nums=[5, 2, 5, 4, 5], k=2))
16+
print(minOperations(nums=[2, 1, 2], k=2))
17+
print(minOperations(nums=[9, 7, 5, 3], k=1))
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# notice the low constraints
2+
# brute force permutations, optimize each step in `solve` with math just in case
3+
4+
from itertools import permutations
5+
6+
7+
def findMinimumTime(strength: list[int], K: int) -> int:
8+
def solve(arr):
9+
inc = 1
10+
time = 0
11+
for i in range(len(arr)):
12+
moves = (arr[i] + inc - 1) // inc # ceil division
13+
time += moves
14+
inc += K
15+
return time
16+
17+
return min(solve(p) for p in permutations(strength))
18+
19+
20+
print(findMinimumTime(strength=[3, 4, 1], K=1))
21+
print(findMinimumTime(strength=[2, 5, 4], K=2))
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# https://leetcode.com/problems/digit-operations-to-make-two-integers-equal
2+
# Dijkstra's algorithm on a custom graph
3+
# note: apparently digits that become 0 don't count anymore...
4+
5+
from heapq import heappush, heappop
6+
7+
MN = 10 ** 5 + 1
8+
is_prime = [True] * MN
9+
is_prime[0] = is_prime[1] = False
10+
for i in range(2, MN):
11+
if is_prime[i]:
12+
for j in range(i * i, MN, i):
13+
is_prime[j] = False
14+
15+
16+
def minOperations(n: int, m: int) -> int:
17+
if is_prime[m] or is_prime[n]:
18+
return -1
19+
20+
def get_adj(num):
21+
res = []
22+
for i in range(len(str(num))):
23+
d = int(str(num)[-i - 1])
24+
if d != 0:
25+
res.append(num - 10 ** i)
26+
if d != 9:
27+
res.append(num + 10 ** i)
28+
return res
29+
30+
q = [(n, n)]
31+
vis = {n: n}
32+
while q:
33+
dist, cur = heappop(q)
34+
if cur == m:
35+
return dist
36+
37+
for adj in get_adj(cur):
38+
if is_prime[adj] or (adj in vis and vis[adj] <= dist + adj):
39+
continue
40+
heappush(q, (dist + adj, adj))
41+
vis[adj] = dist + adj
42+
43+
return -1
44+
45+
46+
print(minOperations(10, 12))
47+
print(minOperations(4, 8))
48+
print(minOperations(6, 2))
49+
print(minOperations(36, 50))
50+
print(minOperations(5637, 2034))
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# https://leetcode.com/problems/count-connected-components-in-lcm-graph
2+
# When only connectivity matters and the number of edges are too high, consider
3+
# using a disjoint set and only connecting necessary edges
4+
#
5+
# - first filter numbers >threshold since the LCM of 2 numbers is at least their maximum
6+
# - loop through all possible divisors <=threshold as the GCD and calculate LCM based on this
7+
# - lcm(a,b) = a*b/gcd(a,b)
8+
9+
class DisjointSet:
10+
def __init__(self, N):
11+
self.parent = [i for i in range(N)]
12+
self.size = [1] * N
13+
14+
def find(self, node):
15+
if self.parent[node] != node: # go up until we reach the root
16+
# attach everything on our way to the root (path compression)
17+
self.parent[node] = self.find(self.parent[node])
18+
return self.parent[node]
19+
20+
def union(self, a, b):
21+
root_a = self.find(a)
22+
root_b = self.find(b)
23+
if root_a == root_b:
24+
return
25+
if self.size[root_b] > self.size[root_a]: # join the smaller to the larger
26+
root_a, root_b = root_b, root_a # swap
27+
self.parent[root_b] = root_a
28+
self.size[root_a] += self.size[root_b]
29+
30+
31+
def countComponents(nums: list[int], threshold: int) -> int:
32+
original_n = len(nums)
33+
nums = [i for i in nums if i <= threshold]
34+
nums = set(nums)
35+
n = len(nums)
36+
37+
ds = DisjointSet(threshold + 1)
38+
39+
for div in range(1, threshold + 1): # loop divisors
40+
res = []
41+
for mul in range(div, threshold + 1, div): # loop multiples of divisors
42+
if mul in nums:
43+
res.append(mul)
44+
for i in range(1, len(res)): # join divisors if LCM < threshold
45+
if res[0] * res[i] <= threshold * div:
46+
ds.union(res[0], res[i])
47+
else: # exceeded threshold, break since res is ascending
48+
break
49+
50+
# count components and single nodes that were filtered out
51+
return sum(ds.find(i) == i for i in nums) + (original_n - n)
52+
53+
54+
print(countComponents(nums=[2, 4, 8, 3, 9], threshold=5))
55+
print(countComponents(nums=[2, 4, 8, 3, 9, 12], threshold=10))

0 commit comments

Comments
 (0)