Skip to content

Commit b5f61f3

Browse files
committed
contest
1 parent 53158b2 commit b5f61f3

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
def buttonWithLongestTime(events) -> int:
2+
mx = events[0][1]
3+
idx = events[0][0]
4+
for i in range(1, len(events)):
5+
t = events[i][1] - events[i - 1][1]
6+
if t > mx or (t == mx and events[i][0] < idx):
7+
idx = events[i][0]
8+
mx = t
9+
return idx
10+
11+
12+
print(buttonWithLongestTime(events=[[1, 2], [2, 5], [3, 9], [1, 15]]))
13+
print(buttonWithLongestTime(events=[[10, 5], [1, 7]]))
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# https://leetcode.com/problems/maximize-amount-after-two-days-of-conversions
2+
# Dijkstra's
3+
# Refer to https://dmoj.ca/problem/dmpg15s6 for optimal solution
4+
# Note: it's probably faster to invert the second graph and only run it once
5+
6+
from typing import List
7+
from collections import defaultdict
8+
from heapq import heappush, heappop
9+
10+
11+
def maxAmount(initialCurrency: str, pairs1: List[List[str]], rates1: List[float], pairs2: List[List[str]],
12+
rates2: list[float]) -> float:
13+
graph1 = defaultdict(list)
14+
for (a, b), c in zip(pairs1, rates1):
15+
graph1[a].append((b, c))
16+
graph1[b].append((a, 1 / c))
17+
18+
graph2 = defaultdict(list)
19+
for (a, b), c in zip(pairs2, rates2):
20+
graph2[a].append((b, c))
21+
graph2[b].append((a, 1 / c))
22+
23+
def search(start, val, graph):
24+
costs = defaultdict(int)
25+
costs[start] = val
26+
pq = [(-val, start)] # make negative for max heap
27+
while pq:
28+
cost, node = heappop(pq)
29+
cost = -cost
30+
31+
for adj, multi in graph[node]:
32+
new_cost = cost * multi
33+
if costs[adj] < new_cost:
34+
costs[adj] = new_cost
35+
heappush(pq, (-new_cost, adj))
36+
return costs
37+
38+
day1 = search(initialCurrency, 1, graph1)
39+
best = 0
40+
for k, val in day1.items():
41+
best = max(best, search(k, val, graph2)[initialCurrency])
42+
43+
return best
44+
45+
46+
print(maxAmount(initialCurrency="EUR", pairs1=[["EUR", "USD"], ["USD", "JPY"]], rates1=[2.0, 3.0],
47+
pairs2=[["JPY", "USD"], ["USD", "CHF"], ["CHF", "EUR"]], rates2=[4.0, 5.0, 6.0]))
48+
print(maxAmount(initialCurrency="NGN", pairs1=[["NGN", "EUR"]], rates1=[9.0], pairs2=[["NGN", "EUR"]], rates2=[6.0]))
49+
print(maxAmount(initialCurrency="USD", pairs1=[["USD", "EUR"]], rates1=[1.0], pairs2=[["EUR", "JPY"]], rates2=[10.0]))
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# https://leetcode.com/problems/count-beautiful-splits-in-an-array
2+
# Any string matching algorithm works
3+
# I used hashing because it's the simplest
4+
# Note: apparently the intended solution is dynamic programming?
5+
6+
from itertools import accumulate
7+
8+
9+
def beautifulSplits(nums: list[int]) -> int:
10+
n = len(nums)
11+
if n < 3: # edge case: no valid splits
12+
return 0
13+
14+
MOD = 177635683940025046467781066894531
15+
p = 53 # p should be greater than max(nums)
16+
17+
power = [0] * n # precompute powers of `p`, with MOD
18+
power[0] = 1
19+
for i in range(1, n):
20+
power[i] = (power[i - 1] * p) % MOD
21+
22+
hash1 = [0] * n # precompute hashes of each character in `str1`
23+
for i in range(n):
24+
hash1[i] = (nums[i] * power[n - i - 1]) % MOD
25+
psa1 = [0] + list(accumulate(hash1)) # psa for range hash query
26+
27+
total = 0
28+
for end1 in range(n):
29+
for end2 in range(end1 + 1, n - 1):
30+
# formula for substring hash: (psa1[r1 + 1] - psa1[l1]) * power[l1] % MOD
31+
32+
# check A is prefix of B
33+
l1 = 0
34+
r1 = end1
35+
l2 = end1 + 1
36+
r2 = end2
37+
if (r1 - l1) <= (r2 - l2): # check prefix
38+
r2 = l2 + r1
39+
hash1 = (psa1[r1 + 1] - psa1[l1]) * power[l1] % MOD # shift up
40+
hash2 = (psa1[r2 + 1] - psa1[l2]) * power[l2] % MOD
41+
if hash1 == hash2:
42+
total += 1
43+
continue
44+
45+
# check B is prefix of C
46+
l1 = end1 + 1
47+
r1 = end2
48+
l2 = end2 + 1
49+
r2 = n - 1
50+
if (r1 - l1) <= (r2 - l2): # check prefix
51+
r2 = l2 + (r1 - l1 + 1) - 1
52+
hash1 = (psa1[r1 + 1] - psa1[l1]) * power[l1] % MOD # shift up
53+
hash2 = (psa1[r2 + 1] - psa1[l2]) * power[l2] % MOD
54+
if hash1 == hash2:
55+
total += 1
56+
57+
return total
58+
59+
60+
print(beautifulSplits([2, 3, 2, 2, 1]))
61+
print(beautifulSplits(nums=[1, 1, 2, 1]))
62+
print(beautifulSplits(nums=[1, 2, 3, 4]))

0 commit comments

Comments
 (0)