标签:oca 运动 nbsp array 遍历 lse 算法思路 原因 跳过
这道题我的思路如下:
1)设机器人的下一个位置是(a,b),那么他的上一个位置最多只有4种情况:(a-1,b),(a+1,b),(a,b-1),(a,b+1)
2)判定机器人能否到达位置(a,b),需要判断两个条件,一是他前面4个位置其中之一是否能够到达,二是位置(a,b)的各位数字之和是否大于k,同时满足这两个条件,那么(a,b)才是一个可以到达的位置。
3)位置(0,0)是一定可以到达的,因为这是初始位置
有了上面几个关键点,接下来就是我们的算法思路:
1、方格是m行n列,对应了一个m行n列的数组,用这个数组来保存该位置是否可达,如果位置可达,那么该位置值为1,不可达值为-1,如果还没有判断这个位置,那么这个位置值为0
2、预处理二维数组,根据所在i行j列,用i和j各位数字之和大于k来先给定一些位置不可达的结论,并且将这些位置的值置为-1
3、理论类似于图的广度优先搜索,实现方法类似于二叉树的层序遍历,从位置(0,0)开始,判断他周围的位置是否可达:
首先将位置(0,0)存入队列
然后将队首元素出队列,判断他四周的位置是否可达,如果四周的位置的值为1,则跳过不处理这个位置,因为这个位置已经被处理过了,如果这个位置的值为0,说明这个位置是可以到达的,将这个位置的值置为1,并且将这个位置的坐标存入队列,如果这个位置的值为-1,说明这个位置不可以到达,跳过这个位置
循环上面这个过程,直到队列为空
此时二维数组中值为1的位置就是可以到达的,值为0的位置就表示虽然该位置坐标各位数之和小于k,但是他周围的位置都不能到达,所以没有路径走到这个位置上,值为-1的位置就是表明不能到达(不能到达的两种原因都可能存在,但是一定有各位数之和大于k这个因素)
所以整个算法的思想就是图的广度优先搜索
代码如下:
package main
import "fmt"
func main() {
fmt.Println(mc(3, 1, 0))
}
// 通过数字之和可以直接判定某些位置不能到达
func reach(x, y, k int) bool {
tmpArray := []int{x, y}
sum := 0
for _, value := range tmpArray {
for value != 0 {
sum += (value % 10)
value /= 10
}
}
if sum <= k {
return true
}
return false
}
func mc(m, n, k int) int {
res := make([][]int, m)
for i := 0; i < m; i++ {
res[i] = make([]int, n)
}
res[0][0] = 1
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if !reach(i, j, k) {
res[i][j] = -1
}
}
}
// queue:=[][]int([0,0],)
queue := make([][]int, 0)
queue = append(queue, []int{0, 0})
// queue[0] = make([]int, 2)
// queue[0][0] = 0
// queue[0][1] = 0
for len(queue) != 0 {
curValue := queue[0]
queue = queue[1:]
if curValue[0]-1 > 0 && res[curValue[0]-1][curValue[1]] == 0 {
res[curValue[0]-1][curValue[1]] = 1
var tmpLocation []int
tmpLocation = append(tmpLocation, curValue[0]-1)
tmpLocation = append(tmpLocation, curValue[1])
queue = append(queue, tmpLocation)
}
if curValue[0]+1 < m && res[curValue[0]+1][curValue[1]] == 0 {
res[curValue[0]+1][curValue[1]] = 1
var tmpLocation []int
tmpLocation = append(tmpLocation, curValue[0]+1)
tmpLocation = append(tmpLocation, curValue[1])
queue = append(queue, tmpLocation)
}
if curValue[1]-1 > 0 && res[curValue[0]][curValue[1]-1] == 0 {
res[curValue[0]][curValue[1]-1] = 1
var tmpLocation []int
tmpLocation = append(tmpLocation, curValue[0])
tmpLocation = append(tmpLocation, curValue[1]-1)
queue = append(queue, tmpLocation)
}
if curValue[1]+1 < n && res[curValue[0]][curValue[1]+1] == 0 {
res[curValue[0]][curValue[1]+1] = 1
var tmpLocation []int
tmpLocation = append(tmpLocation, curValue[0])
tmpLocation = append(tmpLocation, curValue[1]+1)
queue = append(queue, tmpLocation)
}
}
num := 0
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if res[i][j] == 1 {
num++
}
}
}
return num
}
标签:oca 运动 nbsp array 遍历 lse 算法思路 原因 跳过
原文地址:https://www.cnblogs.com/gyyyl/p/13375252.html