【蓝桥杯 每天一道算法题】路径

该问题是一个关于图论和算法的编程挑战。给定一个由2021个节点组成的图,节点间连接基于节点编号之差的绝对值和最小公倍数。目标是找到从节点1到节点2021的最短路径,并用Python实现计算这一路径长度的程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图 中的最短路径。

小蓝的图由 2021 个结点组成,依次编号 1 至 2021。

对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21,则两个结点 之间没有边相连;如果 a 和 b 的差的绝对值小于等于 21,则两个点之间有一条 长度为 a 和 b 的最小公倍数的无向边相连。

例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无 向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为 75。

请计算,结点 1 和结点 2021 之间的最短路径长度是多少。

提示:建议使用计算机编程解决问题。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

答案

# https://www.lanqiao.cn/problems/1460/learning/?page=2&first_category_id=1&sort=students_count
import math
res = [float('inf')] * 2022
res[1] = 0
for i in range(1, 2022):
    for j in range(i + 1, i + 22):
        if j > 2021:
            break
        res[j] = min(res[j], res[i] + math.lcm(i, j))
print(res[-1])


### 关于 C++ 蓝桥杯 DFS 算法题的解析 #### 一、DFS 的基本概念 深度优先搜索(Depth First Search, DFS)是一种常用的图遍历算法,可以通过递归或显式栈的方式实现。在实际编程竞赛中,DFS 经常用于解决诸如迷宫问题、树结构遍历以及组合枚举等问题[^1]。 以下是基于递归方式实现的一个简单 DFS 示例代码: ```cpp #include <iostream> #include <vector> using namespace std; void dfs(int node, vector<vector<int>>& adjList, vector<bool>& visited) { visited[node] = true; cout << "Visited Node: " << node << endl; // 访问当前节点 for (int neighbor : adjList[node]) { if (!visited[neighbor]) { // 如果邻居未被访问,则继续深入 dfs(neighbor, adjList, visited); } } } int main() { int n = 5; // 假设有 5 个节点 vector<vector<int>> adjList(n); // 邻接表表示图 vector<bool> visited(n, false); // 构建邻接表 adjList[0].push_back(1); adjList[0].push_back(2); adjList[1].push_back(3); adjList[1].push_back(4); // 开始 DFS dfs(0, adjList, visited); return 0; } ``` 此代码展示了一个简单的无向图上的 DFS 实现方法,其中 `adjList` 是存储图边关系的邻接表,而 `visited` 数组用来标记哪些节点已经被访问过[^4]。 --- #### 二、剪枝优化的重要性 当面对复杂问题时,单纯的 DFS 往往会因为庞大的搜索空间而导致超时或其他性能瓶颈。因此,“剪枝”成为一种重要的优化手段。通过提前判断某些分支不可能达到最优解或满足条件,可以有效减少不必要的计算量[^2]。 例如,在处理背包问题或者数独求解过程中,如果发现某条路径已经无法达成目标状态,则可以直接终止该路径下的进一步探索。 --- #### 三、具体实例分析——蓝桥杯真题改编 假设有一道典型的蓝桥杯题目如下: **描述**: 给定一棵 N 个结点构成的完全二叉树,根编号为 1 。现在需要统计有多少种不同的子集能够使得这些选中的叶子节点之间互不相邻。 对于此类问题,我们可以利用回溯加记忆化的方法来进行解答;同时也可以考虑适当加入一些约束条件来完成初步筛选工作以加快速度。 下面是针对上述场景设计的一份伪代码框架供参考: ```cpp bool isValid(vector<int>& selectedLeaves){ /* 判断所选出的叶节点集合是否合法 */ } long long countWays(int currentLevel,int lastPickedIndex,vector<int>& candidates){ if(currentLevel > maxLevels){return candidate.size()==requiredSize;} long long res=0; for(auto nextOption:candidates){ if(!isValidSelection(lastPickedIndex,nextOption))continue;//Pruning Step //Make choice selected.push_back(nextOption); //Explore further levels res +=countWays(currentLevel+1 ,nextOption,candidates); //Undo Choice selected.pop_back(); } return res; } ``` 这里的关键在于每次做出选择之前都要先验证其可行性(`!isValidSelection`),这一步骤正是所谓的“剪枝”。 --- ### 总结 综上所述,掌握好基础版的递归形式 DFS 同样重要的是学会根据不同情况灵活运用各种技巧对其进行改进提升效率比如引入剪枝机制等等][^[^24]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值