菜鸟的主题三寻友之旅解答

95 阅读2分钟

当青训营遇上码上掘金

初读题目,是一个数学步行问题,有些类似于万级台阶的问题,在计算机中,我们通常是采用智能算法进行这样的问题的解答。 由于K的数目是小于等于100000的,那么我们需要设计一个数据结构布尔值,有100001个布尔的数组。

那么也可以采用全局搜索的方法进行查找,因为本题的计算量并不算大,通常是采用广度优先算法进行广度搜索,如果是采用深度优先的方法的话,需要设定最大深度,最大深度的值的取值还要恰当,深度越大,越可能找到最优解,但是资源消耗就越大,深度越小,可能找不到最优解,但是资源消耗可以控制。

本题目也可以采用A*算法,取定一个置信函数,用以评量每次结果的优化程度,可以引出启发性的算法,用以减少计算量。在本问题中,置信函数可以是总共的用时。

package main

import (
  "fmt"
  "strings"
	"bufio"
	"os"
  "strconv"
)


var n int;
var k int;
var vis [100001]bool;

func bfs(start int, target int) int {
  var time int = 0
  queue := make([]int, 0)
  queue = append(queue, 1)
  vis[start] = true
  for {
    var length int = len(queue)
    for i := 0; i < length; i++ {
      current := -1
      if len(queue) != 0 {
        current = queue[0]
        queue = queue[1:]
      }
      if current == target {
        return time
      }
      if current - 1 >= 0 && !vis[current - 1] {
        queue = append(queue, current - 1)
        vis[current - 1] = true
      }
      if current + 1 <= 100000 && !vis[current + 1] {
        queue = append(queue, current + 1)
        vis[current + 1] = true
      }
      if current * 2 <= 100000 && !vis[current * 2] {
        queue = append(queue, current * 2)
        vis[current * 2] = true
      }
    }
    time++
    if(len(queue) == 0){
      break
    }
  }
  return -1
}

func main() {
    // var input string
    // _, _ = fmt.Scan(&input)
		scanner := bufio.NewScanner(os.Stdin)
		// fmt.Println(input)
		scanner.Scan()
		input := scanner.Text()
    // 从stdin中取内容直到遇到换行符,停止
    var line = strings.Split(input, " ")
    n, _ := strconv.Atoi(line[0])
    k, _ := strconv.Atoi(line[1])
    if(n == k) {
      fmt.Println(0)
    } else if(n < k) {
      fmt.Println(bfs(n, k))
    } else {
      fmt.Println(n - k)
    }
    // fmt.Println("Hello World go!")
}

在上面的代码中,采用了队列的数据结构对递归函数进行了迭代化,在实际应用中,有时迭代化的优先搜索会更快,有时递归化的优先搜索会更快,最好根据实际情况进行考量。 设计思想是以给定的小青的位置start作为出发点,每次进行步数的执行时,记录下上次到达的位置可以到达的其他的点位置。并用vis数组进行已经访问的点,这样所记录的点一定就是最短的路径。