从报名青训营到现在,使用豆包MarsCodeAI刷题已经将近一个月了,AI刷题的优势与便利想必大家都多多少少体会到了。这里我以做109题《小M的光明之魂速通挑战》的过程为例,展示我是如何用豆包MarsCode来帮助我刷题的,以及我认为豆包MarsCode的优势。
问题描述
小M最近参加了一个名为《光明之魂》的速通比赛。在比赛中,玩家拥有N把武器以及M个Boss需要击败。规则如下:
- 每个Boss有一个唯一的类型编号,用一个正整数表示。
- 每把武器能够击败两种类型的Boss,但每把武器只能使用一次。
- 玩家必须按照给定的顺序逐个击杀Boss,不能跳过Boss顺序。
小M想知道,在不违反规则的前提下,他最多能够击败多少个Boss。
输入变量说明:
n表示拥有的武器数量。m表示需要击败的Boss数量。boss是一个长度为m的列表,表示玩家必须按照顺序击杀的Boss的类型。array是一个长度为n的二维列表,每个元素为[x, y],表示对应的武器可以击败类型为x和y的Boss。
假设我现在刚开始刷题没多久,读题读了几分钟暂时还不知道要从哪里下手,这时我就可以打开侧边栏的AI,点击“需要一点思路提示”
好的,让我们来分析一下这个问题,并提供一些思路提示。
### 问题理解
**目标**:在不违反规则的前提下,尽可能多地击败Boss。
**规则**:
- 每个Boss有一个唯一的类型编号。
- 每把武器可以击败两种类型的Boss,但每把武器只能使用一次。
- 必须按照给定的顺序逐个击杀Boss,不能跳过Boss顺序。
### 数据结构选择
- **武器数组**:`array`,每个元素是一个包含两个整数的列表,表示该武器可以击败的两种类型的Boss。
- **Boss列表**:`boss`,表示需要按照顺序击杀的Boss的类型。
- **武器使用状态**:`used`,一个布尔数组,记录每把武器是否已被使用。
### 算法步骤
**初始化**:
- 创建一个布尔数组 `used`,用于记录每把武器是否已被使用。
- 初始化一个计数器 `defeated_count`,用于记录击败的Boss数量。
**遍历Boss列表**:
- 对于每个Boss,检查是否有未使用的武器可以击败它。
- 如果没有武器可以击败当前Boss,则退出循环。
**选择武器**:
- 对于每个能击败当前Boss的武器,检查它是否能击败后续的Boss。
- 优先选择不能击败后续Boss的武器。
- 如果所有武器都能击败后续Boss,选择能击败最远后续Boss的武器。
**更新状态**:
- 如果找到了合适的武器,则将其标记为已使用,并增加击败的Boss数量。
### 关键点
- **武器选择策略**:优先选择不能击败后续Boss的武器,这样可以最大化后续Boss的击败数量。
- **提前退出**:如果没有武器可以击败当前Boss,则提前退出循环,避免不必要的计算。
通过以上思路,你可以逐步实现代码,确保在不违反规则的前提下,尽可能多地击败Boss。希望这些提示对你有所帮助!
以上是豆包AI给的思路提示,现在我们也大致有解题的思路了:先对武器建立一个used数组,没用过的武器初始化为0,用过的武器设为1,然后对boss列表进行遍历,每次遇到新的boss只在used为0的武器里寻找能击败当前boss的武器,直到没用过的武器都不能击败当前的boss为止。
虽然已经有了思路,但是假设我现在是一个新手,即使有了思路要将思路转化为代码也还是要消耗不少的时间,这时候我们可以在侧边栏的AI点击“给我一些代码提示”,让AI给我们初步实现一些代码
def max_bosses_defeated(n, m, boss, array):
# 初始化武器匹配字典
weapon_map = {}
for i in range(1, n + 1):
weapon_map[i] = []
# 填充武器匹配字典
for i in range(n):
x, y = array[i]
weapon_map[x].append(i)
weapon_map[y].append(i)
# 初始化武器使用状态
used_weapons = [False] * n
# 初始化击杀Boss数量
defeated_count = 0
# 遍历每个Boss
for boss_type in boss:
# 查找是否有未使用的武器可以击败当前Boss
for weapon_index in weapon_map[boss_type]:
if not used_weapons[weapon_index]:
# 使用该武器
used_weapons[weapon_index] = True
defeated_count += 1
break
return defeated_count
# 测试样例
n = 3
m = 5
boss = [1, 2, 3, 4, 5]
array = [[1, 2], [3, 2], [4, 5]]
print(max_bosses_defeated(n, m, boss, array)) # 输出: 2
### 关键步骤解释
1. **初始化武器匹配字典**:
- 创建一个字典`weapon_map`,键为Boss类型,值为可以击败该类型Boss的武器列表。
1. **填充武器匹配字典**:
- 遍历每把武器,将其可以击败的Boss类型添加到对应的列表中。
1. **初始化武器使用状态**:
- 创建一个列表`used_weapons`,记录每把武器是否已经被使用。
1. **遍历每个Boss**:
- 对于每个Boss,检查是否有未使用的武器可以击败它。
- 如果有,使用该武器并标记为已使用,增加击杀Boss数量。
1. **返回结果**:
- 返回成功击杀的Boss数量。
### 注意
- 代码中使用了`break`语句来确保每把武器只使用一次。
- 你可以根据需要调整代码的细节,例如处理边界情况或优化性能。
希望这些代码提示对你有所帮助!如果你有任何具体的问题或需要进一步的解释,请告诉我。
以上是豆包AI给出的代码和对代码的解释,虽然不是直接解决了所有问题但是也给了我们一个大致的代码框架,接下来我们只要在给出的代码上进行进一步的改进就可以了,这比自己从0开始敲所有代码容易不少。
我们先不检查给出的代码是怎么样的,先在编辑区里运行一下,结果报错了
帮我修复一下 [ERROR] Traceback (most recent call last): File "/cloudide/workspace/daimalianxi/topic/v2/73/python/main.py", line 36, in <module> print(max_bosses_defeated(n, m, boss, array)) # 输出: 2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/cloudide/workspace/daimalianxi/topic/v2/73/python/main.py", line 10, in max_bosses_defeated weapon_map[x].append(i) ~~~~~~~~~~^^^ KeyError: 4
我们点击AI fix让AI修复报错
好的,错误信息显示在尝试访问`weapon_map[4]`时出现了`KeyError`,这意味着字典`weapon_map`中没有键为`4`的条目。我们需要确保所有可能的Boss类型都在`weapon_map`中初始化。
### 修复步骤
1. **初始化所有可能的Boss类型**:
- 在初始化`weapon_map`时,确保所有可能的Boss类型都被包含在内。
def max_bosses_defeated(n, m, boss, array):
# 初始化武器匹配字典
weapon_map = {}
for i in range(1, n + 1):
weapon_map[i] = []
# 填充武器匹配字典
for i in range(n):
x, y = array[i]
weapon_map[x].append(i)
weapon_map[y].append(i)
# 初始化武器使用状态
used_weapons = [False] * n
# 初始化击杀Boss数量
defeated_count = 0
# 遍历每个Boss
for boss_type in boss:
# 查找是否有未使用的武器可以击败当前Boss
for weapon_index in weapon_map[boss_type]:
if not used_weapons[weapon_index]:
# 使用该武器
used_weapons[weapon_index] = True
defeated_count += 1
break
return defeated_count
# 测试样例
n = 3
m = 5
boss = [1, 2, 3, 4, 5]
array = [[1, 2], [3, 2], [4, 5]]
print(max_bosses_defeated(n, m, boss, array)) # 输出: 2
可以看到报错原因是weapon_map初始化时本来是想建立所有boss对应的武器的字典但不知道为什么range只到n+1,这里修改为把所有boss都包含到字典里了,重新运行。
输出结果为3,但按样例来说应该输出2才对。我们可以让AI模拟运行样例,由AI返回的结果可以看出击败boss1,2以后boss三已经没有武器可以击败了,但却没有结束,而是继续运行下去,用剩下的武器3击败了boss4并计数了,因此我们应该增加一段在没有武器能击败当前boss的时候结束循环的代码。
因为一直贴AI的回复和修改的代码有些耗时间占位置,以下我就不再贴上AI的回复了。
增加了提前结束的代码后三个样例都通过了。这时我们自信满满的提交,然后返回结果是:第24个样例未通过
让AI分析后知道,这是因为能击败一个boss的武器不止一把,其中有的武器能击败的另一个boss排序更靠后一些,有的武器能击败的另一个boss更靠前一些,这时候就要选择能击败的另一个boss排序靠后的武器,否则就会提前结束,我们让AI增加记录能击败当前boss的武器能击败的另一个boss的顺序,最后选择能击败的另一个boss排序靠后的武器。
最终结果:
def solution(n, m, boss, array):
# 初始化武器匹配字典
weapon_map = {}
for i in range(1, max(boss) + 1): # 初始化所有可能的Boss类型
weapon_map[i] = []
# 填充武器匹配字典
for i in range(n):
x, y = array[i]
weapon_map[x].append(i)
weapon_map[y].append(i)
# 初始化武器使用状态
used_weapons = [False] * n
# 初始化击杀Boss数量
defeated_count = 0
# 遍历每个Boss
for i in range(m):
boss_type = boss[i]
# 查找是否有未使用的武器可以击败当前Boss
possible_weapons = []
for weapon_index in weapon_map[boss_type]:
if not used_weapons[weapon_index]:
possible_weapons.append(weapon_index)
if not possible_weapons:
break # 没有武器能击败当前Boss,结束循环
# 选择能击败的另一个Boss排序靠后的武器
best_weapon = -1
best_future_boss_idx = -1
for w in possible_weapons:
future_boss_idx = m # 初始化为最大值
for k in range(i + 1, m):
if boss[k] in array[w]:
future_boss_idx = k
break
if future_boss_idx > best_future_boss_idx:
best_weapon = w
best_future_boss_idx = future_boss_idx
# 使用最佳武器
if best_weapon != -1:
used_weapons[best_weapon] = True
defeated_count += 1
return defeated_count
# 测试案例
n = 22
m = 25
boss = [11,8,7,4,5,17,16,13,2,20,18,6,10,14,12,22,21,19,1,15,3,9,24,23,25]
array = [[6,22],[18,20],[7,5],[12,5],[17,18],[21,17],[8,4],[18,14],[10,22],[18,2],[24,1],[17,23],[14,7],[15,6],[25,15],[12,6],[11,15],[11,22],[12,1],[2,20],[13,15],[23,8]]
print(solution(n, m, boss, array)) # 期望输出:12
总结: 豆包MarsCode AI刷题降低了我们做题的难度,让我们更容易理解题目,可以帮我们写一部分代码,再根据我们的反馈修改代码,几乎不用自己敲一个代码,实现“自然语言编程”。缺点是豆包AI不能一步到位解决问题,而需要我们指出代码中的不足,并给出修改的建议才能修改,而很难做到自己分析错误并进行合理的修改。由此看出虽然现在AI功能已经挺强大了,但AI也仍然有许多不足,人不会完全被AI替代。