做题笔记:小M的光明之魂速通挑战| 豆包MarsCode AI 刷题

52 阅读3分钟

问题描述

小M最近参加了一个名为《光明之魂》的速通比赛。在比赛中,玩家拥有N把武器以及M个Boss需要击败。规则如下:

  1. 每个Boss有一个唯一的类型编号,用一个正整数表示。
  2. 每把武器能够击败两种类型的Boss,但每把武器只能使用一次。
  3. 玩家必须按照给定的顺序逐个击杀Boss,不能跳过Boss顺序。

小M想知道,在不违反规则的前提下,他最多能够击败多少个Boss。

输入变量说明:

  • n 表示拥有的武器数量。
  • m 表示需要击败的Boss数量。
  • boss 是一个长度为m的列表,表示玩家必须按照顺序击杀的Boss的类型。
  • array 是一个长度为n的二维列表,每个元素为 [x, y],表示对应的武器可以击败类型为 x 和 y 的Boss。

测试样例

  • 样例1

    输入:n = 3 ,m = 5 ,boss = [1, 2, 3, 4, 5] ,array = [[1, 2], [3, 2], [4, 5]]
    输出:2

  • 样例2

    输入:n = 3 ,m = 5 ,boss = [4, 3, 2, 1, 5] ,array = [[1, 2], [3, 2], [4, 5]]
    输出:3

  • 样例3

    输入:n = 4 ,m = 6 ,boss = [1, 2, 3, 4, 5, 6] ,array = [[1, 2], [2, 3], [3, 4], [5, 6]]
    输出:3

解题思路

  • 明确使用深度优先(dfs)。由于题目明确要求每把武器只能使用一次,所以得使用某个数据结构来保存每把武器的使用情况
  • 使用dfs时注意递归的出口,即遍历完所有boss,或在某一boss无法继续递归时,应结束
  • boss只能按顺序击杀所以boss数组不能交换顺序

代码实现

第一步

选取数据结构,表示武器是否使用。可以采用数组,数组第i位代表第i把武器的使用情况,0代表已经使用1代表未使用。我这里采用的map,key是武器的序号,map为bool类型,true代表已使用,false代表未使用。res定义为结果变量。

s := map[int]bool{}
res := 0

第二步

编写dfs递归函数,首先idx表示为当前boss的序号。当该序号等于boss个数时结束递归,同时该序号也是可以击杀的boss数量,所以当idx大于res时,需将idx的值赋予res。遍历每一把武器,使用当前武器击杀boss的前提为,当前武器未使用并且该武器可以击杀当前boss。 如果满足条件,则将该武器状态改为已使用,进行下一个boss的递归,递归完当前武器需要将该武器状态设置为未使用。尝试不选择当前武器,是否还存在其它武器可以击杀当前boss。

	dfs = func(idx int) {
		if idx > res {
			res = idx
		}
		if idx == m {
			return
		}
		for i := 0; i < n; i++ {
			if !s[i] && (array[i][0] == boss[idx] || array[i][1] == boss[idx]) {
				s[i] = true
				dfs(idx + 1)
				s[i] = false
			}
		}
	}

第三步

调用dfs函数,返回res结果

dfs(0)
return res