Skip to content

Commit 7164972

Browse files
committed
Add LeetCode Biweekly Contest 68
1 parent 58d0420 commit 7164972

File tree

8 files changed

+326
-0
lines changed

8 files changed

+326
-0
lines changed

leetcode/biweekly/68/a/a.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package main
2+
3+
import "strings"
4+
5+
// github.com/EndlessCheng/codeforces-go
6+
func mostWordsFound(sentences []string) (ans int) {
7+
for _, s := range sentences {
8+
cnt := strings.Count(s, " ") + 1
9+
if cnt > ans {
10+
ans = cnt
11+
}
12+
}
13+
return
14+
}

leetcode/biweekly/68/a/a_test.go

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

leetcode/biweekly/68/b/b.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package main
2+
3+
// github.com/EndlessCheng/codeforces-go
4+
func findAllRecipes(recipes []string, ingredients [][]string, supplies []string) (ans []string) {
5+
n := len(recipes)
6+
idx := make(map[string]int, n+len(supplies))
7+
for i, r := range recipes {
8+
idx[r] = i + 1
9+
}
10+
for _, s := range supplies {
11+
idx[s] = -1
12+
}
13+
14+
g := make([][]int, n)
15+
deg := make([]int, n)
16+
next:
17+
for i, in := range ingredients {
18+
for _, s := range in {
19+
if idx[s] == 0 { // 没有原材料
20+
deg[i] = -1
21+
continue next
22+
}
23+
}
24+
for _, s := range in {
25+
if j := idx[s]; j > 0 {
26+
g[j-1] = append(g[j-1], i) // 建图
27+
deg[i]++
28+
}
29+
}
30+
}
31+
32+
// 跑拓扑排序
33+
q := []int{}
34+
for i, d := range deg {
35+
if d == 0 {
36+
q = append(q, i)
37+
ans = append(ans, recipes[i])
38+
}
39+
}
40+
for len(q) > 0 {
41+
v := q[0]
42+
q = q[1:]
43+
for _, w := range g[v] {
44+
if deg[w]--; deg[w] == 0 {
45+
q = append(q, w)
46+
ans = append(ans, recipes[w])
47+
}
48+
}
49+
}
50+
return
51+
}

leetcode/biweekly/68/b/b_test.go

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

leetcode/biweekly/68/c/c.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
3+
/* 全部变为左括号或右括号
4+
5+
首先 $s$ 长度不能为奇数,此时应直接返回 $\texttt{false}$。
6+
7+
然后就是用括号问题的经典技巧了:通过一个变量记录括号的平衡度。
8+
9+
以变左括号为例,将所有可以变化的括号变为左括号,如果这样中间还是会出现平衡度小于 $0$ 的情况,那么就返回 $\texttt{false}$。多余的平衡度可以通过将左括号变成右括号来实现
10+
11+
*/
12+
13+
// github.com/EndlessCheng/codeforces-go
14+
func canBeValid(s string, locked string) bool {
15+
if len(s)%2 == 1 {
16+
return false
17+
}
18+
19+
x := 0
20+
for i, ch := range s {
21+
if ch == '(' || locked[i] == '0' { // 能变左就变左
22+
x++
23+
} else if x > 0 {
24+
x--
25+
} else {
26+
return false
27+
}
28+
}
29+
30+
x = 0
31+
for i := len(s) - 1; i >= 0; i-- {
32+
if s[i] == ')' || locked[i] == '0' { // 能变右就变右
33+
x++
34+
} else if x > 0 {
35+
x--
36+
} else {
37+
return false
38+
}
39+
}
40+
return true
41+
}

leetcode/biweekly/68/c/c_test.go

Lines changed: 34 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

leetcode/biweekly/68/d/d.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"math"
6+
"math/bits"
7+
)
8+
9+
/* 拆分成四个问题:计算对数 + 对 1e5 取模 + 计算尾零个数 + 判断剩余数字的长度
10+
11+
我们拆分成四个问题来算:
12+
13+
- 计算 $\textit{pre}$;
14+
- 计算 $\textit{suf}$;
15+
- 计算 $C$;
16+
- 判断剩余数字的长度是否超过 $10$。
17+
18+
#### 1. 计算 $\textit{pre}$
19+
20+
我们可以通过取以 $10$ 为底的对数的方式,将乘法转换成加法,即如下法则:
21+
22+
$$
23+
a\cdot b = 10^{\log_{10}a}\cdot 10^{\log_{10}b} = 10^{\log_{10}a+\log_{10}b}
24+
$$
25+
26+
记最后得到的指数为 $e$,则有
27+
28+
$$
29+
\textit{pre} = 10^{e-\lfloor e \rfloor} \cdot 10000 = 10^{e-\lfloor e \rfloor + 4}
30+
$$
31+
32+
#### 2. 计算 $C$
33+
34+
先来看怎么计算尾零。这相当于求乘积中能分解出来的 $10$ 的个数。
35+
36+
我们可以将所有整数分解质因子,那么分解出来的 $2$ 的幂次之和,以及 $5$ 的幂次之和,这两者的较小值就是最后乘积中能分解出来的 $10$ 的个数。
37+
38+
#### 3. 计算 $\textit{suf}$
39+
40+
我们可以将每个数字的所有因子 $2$ 和 $5$ 去掉,然后将剩下的数字相乘,由于我们只取末 $5$ 位,所以在乘法的过程中可以对 $10^5$ 取模。
41+
42+
由于可能会多去掉一些 $2$ 或 $5$,在遍历 $[\textit{left},\textit{right}]$ 结束后还需要再重新乘上多去掉的 $2$ 或 $5$。
43+
44+
#### 4. 判断剩余数字的长度是否超过 $10$
45+
46+
在上一条的过程中额外计算一个乘积,判断其是否大于或等于 $10^{10}$。
47+
48+
*/
49+
50+
// github.com/EndlessCheng/codeforces-go
51+
func abbreviateProduct(left, right int) string {
52+
e, cnt2, cnt5, suf, mul := 0.0, 0, 0, 1, 1
53+
update := func(x int) {
54+
suf = suf * x % 1e5
55+
if mul != -1 {
56+
mul *= x
57+
if mul >= 1e10 {
58+
mul = -1
59+
}
60+
}
61+
}
62+
63+
for i := left; i <= right; i++ {
64+
e += math.Log10(float64(i))
65+
x := i
66+
tz := bits.TrailingZeros(uint(x)) // 因子 2 的个数
67+
cnt2 += tz
68+
x >>= tz
69+
for ; x%5 == 0; x /= 5 {
70+
cnt5++ // 因子 5 的个数
71+
}
72+
update(x)
73+
}
74+
cnt10 := min(cnt2, cnt5)
75+
for i := cnt10; i < cnt2; i++ {
76+
update(2) // 补上多拆出来的 2
77+
}
78+
for i := cnt10; i < cnt5; i++ {
79+
update(5) // 补上多拆出来的 5
80+
}
81+
82+
if mul != -1 { // 不需要缩写
83+
return fmt.Sprintf("%de%d", mul, cnt10)
84+
}
85+
pre := int(math.Pow(10, e-math.Floor(e)+4))
86+
return fmt.Sprintf("%d...%05de%d", pre, suf, cnt10)
87+
}
88+
89+
func min(a, b int) int { if a > b { return b }; return a }

leetcode/biweekly/68/d/d_test.go

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)