67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package q1970
|
|
|
|
var dirs = [4][2]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}
|
|
|
|
func isPossibleOnDay(row, col int, cells [][]bool, day int, floods [][]int) bool {
|
|
for i := range col {
|
|
cells[0][i] = true
|
|
}
|
|
for i := range row - 1 {
|
|
copy(cells[i+1], cells[0])
|
|
}
|
|
for i := range day {
|
|
cells[floods[i][0]-1][floods[i][1]-1] = false
|
|
}
|
|
|
|
// Use bfs to find a path from top to bottom
|
|
queue := make([][2]int, 0, col) // {row, col}
|
|
for x, ok := range cells[0] {
|
|
if ok {
|
|
queue = append(queue, [2]int{0, x})
|
|
cells[0][x] = false
|
|
}
|
|
}
|
|
for ; len(queue) > 0; queue = queue[1:] {
|
|
r, c := queue[0][0], queue[0][1]
|
|
for _, d := range dirs {
|
|
tr, tc := r+d[0], c+d[1]
|
|
if tr < 0 || tc < 0 || tr >= row || tc >= col {
|
|
continue
|
|
}
|
|
if !cells[tr][tc] {
|
|
continue
|
|
}
|
|
if tr == row-1 {
|
|
return true // reached bottom
|
|
}
|
|
cells[tr][tc] = false
|
|
queue = append(queue, [2]int{tr, tc})
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func latestDayToCross(row int, col int, cells [][]int) int {
|
|
walkableBuf := make([]bool, col*row)
|
|
walkable := make([][]bool, row)
|
|
for i := range row {
|
|
walkable[i] = walkableBuf[i*col : (i+1)*col]
|
|
}
|
|
|
|
// Use binary search to find the last day
|
|
l, r := 1, len(cells)+1
|
|
for l < r {
|
|
if l+1 == r {
|
|
return l
|
|
}
|
|
m := (l + r) / 2
|
|
if isPossibleOnDay(row, col, walkable, m, cells) {
|
|
l = m
|
|
} else {
|
|
r = m
|
|
}
|
|
}
|
|
return 0 // impossible
|
|
}
|
|
|
|
var _ = latestDayToCross
|