news 2026/6/20 19:10:20

《算法竞赛从入门到国奖》算法基础:搜索-DFS初识

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《算法竞赛从入门到国奖》算法基础:搜索-DFS初识

💡Yupureki:个人主页

✨个人专栏:《C++》 《算法》


🌸Yupureki🌸的简介:


目录

前言

1. 选数

算法原理

实操代码

2. 飞机降落

算法原理

实操代码

3. 八皇后 Checker Challenge

算法原理

实操代码


前言

DFS全称深度优先搜索,相当于是函数递归。其核心思想为"尽可能深"地搜索分支,直到遇到尽头再回溯

1. 选数

题目链接:

P1036 [NOIP 2002 普及组] 选数 - 洛谷

算法原理

对于每个数我们都有两种选择:选和不选

因此我们用dfs,枚举所有选择的情况,当选择的个数为3没有数可选时返回

当然我们选择数也不是乱选,我们在dfs函数中添加一个参数pos,为从数组下标为pos的位置开始选数

由于要统计实时的选择的数的总和以及选择的个数,因此我们定义:

  • sum为选择的数的总和
  • cnt为选择的数的个数
  • ret为总和为素数的结果

当cnt == 3时,判断sum是否为素数,因此要自己实现一个判断素数的函数

实操代码

#include <iostream> #include <vector> #include <cmath> using namespace std; vector<int> v; int n, k; int sum = 0; int cnt = 0; int ret = 0; bool isprime(int num)//判断是否为素数 { if (num <= 1)return false; if (num <= 3)return true; if (num % 2 == 0 || num % 3 == 0)return false; for(int i = 5; i <= sqrt(num);i++) { if (num % i == 0) return false; } return true; } void dfs(int pos)//从下标为pos的位置开始选数 { if (cnt == k) { if (isprime(sum)) ret++; return; } for (int i = pos; i < n; i++) { sum += v[i]; cnt++; dfs(i + 1); cnt--; sum -= v[i]; } return; } int main() { cin >> n >> k; for (int i = 0; i < n; i++) { int num = 0; cin >> num; v.push_back(num); } dfs(0); cout << ret; return 0; }

2. 飞机降落

题目链接:

P9241 [蓝桥杯 2023 省 B] 飞机降落 - 洛谷

算法原理

由于bfs是暴力枚举,因此使用bfs的前提是数据量不能大,一般10到20是合适的

而这个时候发现T小于或等于10,因此可以无脑使用bfs

我们枚举所有的飞机先后降落顺序的全排列,当安排完后进行判断:

  • 如果无法正常降落,回退继续枚举
  • 如果可以正常降落,直接退出bfs

当全排列的时候,每一次递归我们只能选择没有选过的飞机并且我们得全部选上,因此我们得用一个bool数组,来记录哪些飞机选了,哪些飞机没选

实操代码

#include <iostream> #include <vector> using namespace std; int n; vector<int> T; vector<int> D; vector<int> L; vector<int> ret; vector<bool> st;//飞机是否选中:true为选了;false为没选 bool check() { int time = T[ret[0]]; for (auto& it : ret) { int curtime = max(time,T[it]); if(curtime > T[it] + D[it]) return false; time = curtime + L[it]; } return true; } bool dfs() { if (ret.size() == n) { if (check()) { cout << "YES"<<endl; return true; } return false; } for (int i = 0; i < n; i++) { if (st[i] == false)//当飞机没选时,选上 { ret.push_back(i); st[i] = true; if (dfs()) return true; ret.pop_back(); st[i] = false; } } return false; } int main() { int group; cin >> group; while (group--) { T.clear(); D.clear(); L.clear(); st.clear(); ret.clear(); cin >> n; st.resize(n); for (int i = 0; i < n; i++) { int a, b, c; cin >> a >> b >> c; T.push_back(a); D.push_back(b); L.push_back(c); } if (dfs() == false) cout << "NO" << endl; } return 0; }

3. 八皇后 Checker Challenge

题目链接:

P1219 [USACO1.5] 八皇后 Checker Challenge - 洛谷

算法原理

我们先一行一行地选择,每一行选择的情况必须满足以下条件:

  • 每一列只有一个
  • 每一条对角线只有一个

返回条件:

如果在一行发现没有可选的情况,则直接返回;

当最后一行选择完成后,就算这个选法是对的,随后记录下来

保证每一列只有一个是很好判断的,重点是如何判断对角线的情况

根据初中的平面直角坐标系,我们可以得到:两条对角线的方程

我们把两条直线x = 0和x = n分别当作每条对角线的映射关系:

y = -x + (i + j)打在x = 0上的点的集合表示该对角线的选择情况

y = x + (j - i)打在x = n上的带你的集合表示该对角线的选择情况

对应在数组中,即

  • y[j- i + n] = true,表示y = x + (j - i)这条「主对角线」上放置了一个皇后;
  • x[j + i] = true,表示y = -x + (i + j)这条「副对角线」上放置了一个皇后。

实操代码

#include <iostream> #include <vector> using namespace std; int n; int ret = 0; vector<int> v; vector<bool> st; vector<bool> x; vector<bool> y; void dfs() { if (v.size() == n) { ret++; if (ret <= 3) { for (auto& it : v) cout << it + 1 << " "; cout << endl; } return; } for (int i = 0; i < n; i++) { if (st[i] == false && x[i + v.size()] == false && y[i - v.size() + n] == false) { x[i + v.size()] = true; y[i - v.size() + n] = true; v.push_back(i); st[i] = true; dfs(); v.pop_back(); x[i + v.size()] = false; y[i - v.size() + n] = false; st[i] = false; } } return; } int main() { cin >> n; st.resize(n,false); x.resize(2 * n, false); y.resize(2 * n, false); dfs(); cout << ret; return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/18 20:32:34

知网AI率降到10%以下?这4款降AI工具亲测有效

知网AI率降到10%以下&#xff1f;这4款降AI工具亲测有效 TL;DR 太长不看 知网AI率降到10%以下不是梦&#xff0c;关键是选对工具。实测4款有效的降AI工具&#xff1a;比话降AI专攻知网检测&#xff08;承诺15%以下&#xff0c;不达标退款&#xff09;&#xff0c;嘎嘎降AI性价比…

作者头像 李华
网站建设 2026/6/18 21:47:51

手把手教你降AI率:从检测到处理到验证的完整操作指南

手把手教你降AI率&#xff1a;从检测到处理到验证的完整操作指南 TL;DR 太长不看 降AI率完整流程分5步&#xff1a;检测&#xff08;先知道AI率多高&#xff09;→分析&#xff08;定位高风险段落&#xff09;→处理&#xff08;用专业工具降AI&#xff09;→校对&#xff08;检…

作者头像 李华
网站建设 2026/6/18 21:46:53

Java毕设项目推荐-基于springboot的游泳馆管理课程发布、学员预约、课时统计,系统智能系统供课程预约、泳池信息查询、在线充值、教学管理【附源码+文档,调试定制服务】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/13 14:53:08

AIGC率优化工具网站排行榜:10大平台免费与付费方案对比

&#xfffd;&#xfffd; 10大降AIGC平台核心对比速览 排名 工具名称 降AIGC效率 适用场景 免费/付费 1 askpaper ⭐⭐⭐⭐⭐ 学术论文精准降AI 付费 2 秒篇 ⭐⭐⭐⭐⭐ 快速降AIGC降重 付费 3 Aibiye ⭐⭐⭐⭐ 多学科论文降AI 付费 4 Aicheck ⭐⭐⭐⭐…

作者头像 李华
网站建设 2026/6/11 0:38:45

Java计算机毕设之基于springboot+vue的智能药箱系统智能药品管理系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/19 17:33:38

利用AI技术改进的开题报告模板,让学术研究的第一步更加高效便捷

AI开题报告工具对比速览 工具名称 核心功能 生成速度 适用场景 独特优势 AIbiye 全流程论文辅助 3-5分钟 从开题到定稿 深度学术逻辑构建 AIcheck 精准开题生成 2-3分钟 快速产出初稿 国内院校模板库 AskPaper 文献综述辅助 实时响应 研究现状分析 海量文献…

作者头像 李华