标签: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