Skip to content

Commit

Permalink
update codes and links
Browse files Browse the repository at this point in the history
  • Loading branch information
EndlessCheng committed Apr 18, 2020
1 parent b98b1c2 commit a39d449
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 199 deletions.
219 changes: 22 additions & 197 deletions copypasta/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -842,8 +842,6 @@ func monotoneCollection() {
}

// NOTE: 对于搜索格子的题,可以不用创建 vis 而是通过修改格子的值为范围外的值(如零、负数、'#' 等)来做到这一点
// 剪枝: https://blog.csdn.net/weixin_43914593/article/details/104613920
// A*: https://blog.csdn.net/weixin_43914593/article/details/104935011
func loopCollection() {
dir4 := [...][2]int{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}
min := func(a, b int) int {
Expand All @@ -859,39 +857,6 @@ func loopCollection() {
return b
}

loopDiagonal := func(mat [][]int) {
n, m := len(mat), len(mat[0])
for j := 0; j < m; j++ {
for i := 0; i < n; i++ {
if i > j {
break
}
_ = mat[i][j-i]
}
}
for i := 1; i < n; i++ {
for j := m - 1; j >= 0; j-- {
if i+m-1-j >= n {
break
}
_ = mat[i+m-1-j][j]
}
}
}

loopDiagonal2 := func(n int) {
for sum := 0; sum < 2*n-1; sum++ {
for x := 0; x <= sum; x++ {
y := sum - x
if x >= n || y >= n {
continue
}
Println(x, y)
}
Println()
}
}

// 枚举 {0,1,...,n-1} 的全部子集
loopSet := func(arr []int) {
n := len(arr)
Expand Down Expand Up @@ -929,81 +894,6 @@ func loopCollection() {
}
}

// 枚举排列 + 剪枝
// 即有 n 个位置,枚举每个位置上可能出现的值(范围在 sets 中),且每个位置上的元素不能重复
// 例题见 LC169D
loopPerm := func(n int, sets []int) bool {
used := make([]bool, len(sets))
//used := [10]bool{}
var f func(cur, x, y int) bool
f = func(pos, x, y int) bool {
if pos == n {
return true // custom
}
// 对每个位置,枚举可能出现的值,跳过已经枚举的值
for i, v := range sets {
_ = v
// custom pruning
//if {
// continue
//}
if used[i] {
continue
}
used[i] = true
// custom calc x y
if f(pos+1, x, y) {
return true
}
used[i] = false
}
return false
}
return f(0, 0, 0)
}

dfsGrids := func(grid [][]int) (comps int) {
// grid[i][j] = 0 or 1
n, m := len(grid), len(grid[0])
vis := make([][]bool, n)
for i := range vis {
vis[i] = make([]bool, m)
}
var dfs func(i, j int) bool
dfs = func(i, j int) bool {
if i < 0 || i >= n || j < 0 || j >= m {
return false
}
if grid[i][j] == 1 {
return true
}
if vis[i][j] {
return true
}
vis[i][j] = true
res := true
for _, dir := range dir4 {
if !dfs(i+dir[0], j+dir[1]) {
// 遍历完该连通分量再 return
//if {
// res = false
//}
}
}
return res
}
for i, gi := range grid {
for j, gij := range gi {
if gij == 0 && !vis[i][j] {
if dfs(i, j) {
comps++
}
}
}
}
return
}

/*
遍历以 (centerI, centerJ) 为中心的欧几里得距离为 dis 范围内的格点
例如 dis=2 时:
Expand Down Expand Up @@ -1056,106 +946,41 @@ func loopCollection() {
}
}

// 从数组 a 中选择 [0,min(r,len(a))] 个元素,生成所有组合
// vals 初始化为 make([]int, 0, min(r,len(a)))
var rangeCombinations func(a []int, r int, vals []int, do func(vals []int))
rangeCombinations = func(a []int, r int, vals []int, do func([]int)) {
do(vals)
if len(vals) < r {
for i, v := range a {
rangeCombinations(a[i+1:], r, append(vals, v), do)
}
}
}

// 从一个长度为 n 的数组中选择 r 个元素,生成所有组合,每个组合用下标表示
// r must <= n
// 由于实现上直接传入了 indexes,所以在 do 中不能修改 indexes。若要修改则代码在传入前需要 copy 一份
// 参考 https://docs.python.org/3/library/itertools.html#itertools.combinations
// https://stackoverflow.com/questions/41694722/algorithm-for-itertools-combinations-in-python
combinations := func(n, r int, do func(indexes []int)) {
indexes := make([]int, r)
for i := range indexes {
indexes[i] = i
}
do(indexes)
for {
i := r - 1
for ; i >= 0; i-- {
if indexes[i] != i+n-r {
loopDiagonal := func(mat [][]int) {
n, m := len(mat), len(mat[0])
for j := 0; j < m; j++ {
for i := 0; i < n; i++ {
if i > j {
break
}
_ = mat[i][j-i]
}
if i == -1 {
return
}
indexes[i]++
for j := i + 1; j < r; j++ {
indexes[j] = indexes[j-1] + 1
}
do(indexes)
}
}

// 从一个长度为 n 的数组中选择 r 个元素,生成所有排列,每个排列用下标表示
// r must <= n
// 由于实现上直接传入了 indexes,所以在 do 中不能修改 indexes。若要修改则代码在传入前需要 copy 一份
// 参考 https://docs.python.org/3/library/itertools.html#itertools.permutations
permutations := func(n, r int, do func(indexes []int)) {
indexes := make([]int, n)
for i := range indexes {
indexes[i] = i
}
do(indexes[:r])
cycles := make([]int, r)
for i := range cycles {
cycles[i] = n - i
}
for {
i := r - 1
for ; i >= 0; i-- {
cycles[i]--
if cycles[i] == 0 {
tmp := indexes[i]
copy(indexes[i:], indexes[i+1:])
indexes[n-1] = tmp
cycles[i] = n - i
} else {
j := cycles[i]
indexes[i], indexes[n-j] = indexes[n-j], indexes[i]
do(indexes[:r])
for i := 1; i < n; i++ {
for j := m - 1; j >= 0; j-- {
if i+m-1-j >= n {
break
}
}
if i == -1 {
return
_ = mat[i+m-1-j][j]
}
}
}

// 注意这个不是按照字典序 do 的
// Permute the values at index i to len(arr)-1.
// See 910C for example.
var permute func([]int, int, func([]int))
permute = func(arr []int, i int, do func([]int)) {
if i == len(arr) {
do(arr)
return
}
permute(arr, i+1, do)
for j := i + 1; j < len(arr); j++ {
arr[i], arr[j] = arr[j], arr[i]
permute(arr, i+1, do)
arr[i], arr[j] = arr[j], arr[i]
loopDiagonal2 := func(n int) {
for sum := 0; sum < 2*n-1; sum++ {
for x := 0; x <= sum; x++ {
y := sum - x
if x >= n || y >= n {
continue
}
Println(x, y)
}
Println()
}
}
permuteAll := func(arr []int, do func([]int)) { permute(arr, 0, do) }

// 舞蹈链
// TODO: https://oi-wiki.org/search/dlx/

_ = []interface{}{
loopDiagonal, loopDiagonal2, loopSet, loopSubset, loopSubsetK, loopPerm, dfsGrids, searchDir4, searchDir4R,
rangeCombinations, combinations, permutations, permuteAll,
loopSet, loopSubset, loopSubsetK,
searchDir4, searchDir4R, loopDiagonal, loopDiagonal2,
}
}
6 changes: 4 additions & 2 deletions copypasta/dp.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,12 @@ func dpCollections() {
*/
digitDP := func(lower, upper string) int {
const mod int = 1e9 + 7
n := len(upper) // assert len(lower) == len(upper)

// <=s 的符合要求的数字/字符串数目
calc := func(s string) int {
// 有些题 lowerC 要从 1 开始,而 0 的部分单独计算(由于 0 后面可以填所有数字,这部分可以用 ∑_p>0 f(p, false) 来算)
const lowerC, upperC byte = '0', '9'
n := len(s)
dp := make([][]int, n)
for i := range dp {
dp[i] = make([]int, n)
Expand Down Expand Up @@ -397,11 +397,13 @@ func dpCollections() {
// TODO: 斜率优化 / 凸包优化 (CHT)
// https://oi-wiki.org/dp/opt/slope/
// https://codeforces.com/blog/entry/63823
// todo https://blog.csdn.net/weixin_43914593/article/details/105560357
// todo https://luckyglass.github.io/2019/19Dec21stArt1/
// 一类单调问题的求解(宋新波) http://www.doc88.com/p-2953873379975.html

// TODO: 四边形不等式优化
// https://oi-wiki.org/dp/opt/quadrangle/
// https://blog.csdn.net/weixin_43914593/article/details/105150937
// todo https://blog.csdn.net/weixin_43914593/article/details/105150937

/* 树形 DP
https://codeforces.com/blog/entry/20935
Expand Down
Loading

0 comments on commit a39d449

Please sign in to comment.