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