Skip to content

Commit 41138b1

Browse files
committed
2021 力扣杯秋季个人赛(Rank 26)
1 parent 59b6e62 commit 41138b1

File tree

10 files changed

+490
-0
lines changed

10 files changed

+490
-0
lines changed

leetcode/season/2021fall/a/a.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package main
2+
3+
/*
4+
用哈希表统计差异
5+
6+
*/
7+
8+
// github.com/EndlessCheng/codeforces-go
9+
func minimumSwitchingTimes(source, target [][]int) (ans int) {
10+
cnt := map[int]int{}
11+
for i, row := range source {
12+
for j, v := range row {
13+
cnt[v]++
14+
cnt[target[i][j]]--
15+
}
16+
}
17+
for _, c := range cnt {
18+
ans += abs(c)
19+
}
20+
return ans / 2
21+
}
22+
23+
func abs(x int) int {
24+
if x < 0 {
25+
return -x
26+
}
27+
return x
28+
}

leetcode/season/2021fall/a/a_test.go

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

leetcode/season/2021fall/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+
import "sort"
4+
5+
/*
6+
排序+贪心
7+
8+
将 $\textit{cards}$ 从大到小排序,并累加前 $\textit{cnt}$ 个元素之和,记作 $\textit{sum}$,若 $\textit{sum}$ 是偶数则直接返回,若不是偶数,则我们需要从前 $\textit{cnt}$ 个元素中选一个元素 $x$,并从后面找一个最大的且奇偶性和 $x$ 不同的元素替换 x,这样就可以使 $\textit{sum}$ 为偶数。
9+
10+
为了使 $\textit{sum}$ 尽可能大,我们需要使替换前后的变化尽可能地小,我们分两种情况讨论:
11+
12+
- 替换 $\textit{card}[\textit{cnt}-1]$;
13+
- 替换前 $\textit{cnt}$ 个元素中,最小的且奇偶性和 $\textit{card}[\textit{cnt}-1]$ 不同的元素。
14+
15+
*/
16+
17+
// github.com/EndlessCheng/codeforces-go
18+
func maxmiumScore(cards []int, cnt int) (ans int) {
19+
sort.Sort(sort.Reverse(sort.IntSlice(cards)))
20+
sum := 0
21+
for _, v := range cards[:cnt] {
22+
sum += v
23+
}
24+
if sum&1 == 0 {
25+
return sum
26+
}
27+
// 在 cards[cnt:] 中找一个最大的且奇偶性和 x 不同的元素,替换 x
28+
replace := func(x int) {
29+
for _, v := range cards[cnt:] {
30+
if v&1 != x&1 {
31+
ans = max(ans, sum-x+v)
32+
break
33+
}
34+
}
35+
}
36+
replace(cards[cnt-1]) // 替换 cards[cnt-1]
37+
for i := cnt - 2; i >= 0; i-- {
38+
if cards[i]&1 != cards[cnt-1]&1 { // 找一个最小的且奇偶性不同于 cards[cnt-1] 的元素,将其替换掉
39+
replace(cards[i])
40+
break
41+
}
42+
}
43+
return
44+
}
45+
46+
func max(a, b int) int {
47+
if b > a {
48+
return b
49+
}
50+
return a
51+
}

leetcode/season/2021fall/b/b_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/season/2021fall/c/c.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package main
2+
3+
// 暴力枚举
4+
5+
// 枚举每个空格,放上黑棋后,统计能翻转多少白棋,然后就是一些实现细节了,具体见代码注释
6+
7+
// github.com/EndlessCheng/codeforces-go
8+
var dir8 = []struct{ x, y int }{{1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}}
9+
10+
func cntFlip(g [][]byte) (cnt int) {
11+
n, m := len(g), len(g[0])
12+
for { // 不断循环,直到无法翻转白棋
13+
flip := false
14+
for i, row := range g {
15+
for j, ch := range row {
16+
if ch != 'O' {
17+
continue
18+
}
19+
// 对于每个白棋,检查行、列或对角线中是否存在两端均有黑棋,且中间没有空白
20+
outer:
21+
for k, d := range dir8[:4] {
22+
// 检查一个方向
23+
for x, y := i, j; ; x, y = x+d.x, y+d.y {
24+
if x < 0 || x >= n || y < 0 || y >= m || g[x][y] == '.' {
25+
continue outer
26+
}
27+
if g[x][y] == 'X' {
28+
break
29+
}
30+
}
31+
// 检查相反的另一方向
32+
d = dir8[k+4]
33+
for x, y := i, j; ; x, y = x+d.x, y+d.y {
34+
if x < 0 || x >= n || y < 0 || y >= m || g[x][y] == '.' {
35+
continue outer
36+
}
37+
if g[x][y] == 'X' {
38+
break
39+
}
40+
}
41+
// 将其翻转为黑棋
42+
g[i][j] = 'X'
43+
flip = true
44+
cnt++
45+
break
46+
}
47+
}
48+
}
49+
if !flip {
50+
return
51+
}
52+
}
53+
}
54+
55+
func flipChess(g []string) (ans int) {
56+
g2 := make([][]byte, len(g))
57+
for i, row := range g {
58+
for j, ch := range row {
59+
if ch == '.' {
60+
for k, r := range g {
61+
g2[k] = []byte(r)
62+
}
63+
g2[i][j] = 'X' // 放上黑棋
64+
if cnt := cntFlip(g2); cnt > ans {
65+
ans = cnt
66+
}
67+
}
68+
}
69+
}
70+
return
71+
}

leetcode/season/2021fall/c/c_test.go

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

leetcode/season/2021fall/d/d.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package main
2+
3+
import (
4+
"sort"
5+
)
6+
7+
/* 二分+暴力枚举
8+
9+
注意到半径很小,我们可以枚举每个玩具,并暴力枚举该玩具**周围**是否有可以套住该玩具的圈。
10+
11+
具体来说,将 $\textit{circles}$ 排序后,将横坐标相同的圈分为一组。对每个玩具,可以套住该玩具的圈,在横坐标上,必然满足圈的最右端点不小于玩具的最右端点,且圈的最左端点不超过玩具的最左端点。对于纵坐标也是类似。这样我们可以二分要枚举的圈的初始位置,并向后遍历即可。
12+
13+
*/
14+
15+
// github.com/EndlessCheng/codeforces-go
16+
func circleGame(toys [][]int, circles [][]int, r0 int) (ans int) {
17+
sort.Slice(circles, func(i, j int) bool { a, b := circles[i], circles[j]; return a[0] < b[0] || a[0] == b[0] && a[1] < b[1] })
18+
19+
// 将横坐标相同的圈分为一组
20+
type pair struct{ x, y int }
21+
a, y := [][]pair{}, -1
22+
for _, p := range circles {
23+
if len(a) == 0 || p[0] > a[len(a)-1][0].x {
24+
a = append(a, []pair{{p[0], p[1]}})
25+
y = -1
26+
} else if p[1] > y { // 去重
27+
a[len(a)-1] = append(a[len(a)-1], pair{p[0], p[1]})
28+
y = p[1]
29+
}
30+
}
31+
32+
outer:
33+
for _, t := range toys {
34+
x, y, r := t[0], t[1], t[2]
35+
if r > r0 {
36+
continue
37+
}
38+
i := sort.Search(len(a), func(i int) bool { return a[i][0].x+r0 >= x+r })
39+
for ; i < len(a); i++ {
40+
col := a[i]
41+
if col[0].x-r0 > x-r {
42+
break
43+
}
44+
j := sort.Search(len(col), func(j int) bool { return col[j].y+r0 >= y+r })
45+
for ; j < len(col); j++ {
46+
c := col[j]
47+
if c.y-r0 > y-r {
48+
break
49+
}
50+
if (x-c.x)*(x-c.x)+(y-c.y)*(y-c.y) <= (r0-r)*(r0-r) {
51+
ans++
52+
continue outer
53+
}
54+
}
55+
}
56+
}
57+
return
58+
}

leetcode/season/2021fall/d/d_test.go

Lines changed: 81 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)