蓝桥杯练习题总结(二)dfs题、飞机降落、全球变暖

目录

一、飞机降落

二、全球变暖

初始化和输入

确定岛屿

DFS搜索判断岛屿是否会被淹没

 计算被淹没的岛屿数量

三、军训排队 


一、飞机降落

问题描述:

N架飞机准备降落到某个只有一条跑道的机场。其中第 i 架飞机在 T_i时刻到达机场上空,到达时它的剩余油料还可以继续盘旋 D_i个单位时间,即它最早可以于 1, 时刻开始降落,最晚可以于T_i+D_i时刻开始降落。降落过程需要L_i个单位时间。

输入格式:

输入包含多组数据。

第一行包含一个整数N,代表测试数据的组数。

对于每组数据:

第一行包含一个整数T,代表测试数据的组数。

对于每组数据,第一行包含一个整数 N。
接下来的N行,每行包含三个整数T_i,D_i,L_i
输出格式:

对于每组数据,输出YES或者NO,代表是否可以全部安全降落。

输入样例:

2
3
0 100 10
10 10 10
0 2 20
3
0 10 20
10 10 20
20 10 20

输出样例:

YES
NO

思路:

  • 首先读取飞机的数量N,然后读取每架飞机的到达时间t、盘旋时间d和降落时间l。
  • 使用深度优先搜索(DFS)尝试所有可能的降落顺序。DFS的过程中,我们需要一个bool数组来记录每架飞机的降落状态(例如,是否已经降落)。
bool st[N];// 判断当前飞机是否已经降落
  • 循环遍历如果当前尝试的飞机不能在剩余油料允许的时间内降落,或者尝试完所有飞机后没有找到合法的降落顺序,则回溯到上一个状态,尝试另一种降落顺序。
  • 对于每一架尝试降落的飞机,检查它是否能够在剩余油料允许的时间内开始降落,即降落的开始时间应该在到达时间加盘旋时间的范围内(t_i + d_i< 上一次降落时间 + l_{i-1}  )。
if (p[i].t + p[i].d < time)
// 如果当前时间超过了飞机的最晚降落时间
{//回溯,回溯到DFS之前的状态。st[i] = false;return false;
}
int t = max(time, p[i].t) + p[i].l;// 此次降落时间
  • 如果当前尝试的飞机可以降落,更新该飞机的状态为已降落,并更新跑道的可用时间为该飞机降落完成的时间。
int t = max(time, p[i].t) + p[i].l;
if (dfs(u + 1, t))return true;
  • 如果找到了一个所有飞机都能在其剩余油料允许的时间内完成降落的顺序,则输出"YES",否则输出"NO"。
  • 重置st数组,准备下一组数据
for (int i = 0; i < n; i++)st[i] = false;
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 10 + 20;struct plane {ll t,// 到达上空时间d,// 可盘旋时间l;// 降落所需时间}p[N];bool st[N];// 判断当前飞机是否已经降落ll n;// 飞机个数。// u表示已经有U架飞机成功降落了。
// time表示当前的时间,前一架飞机落地的时间。
bool dfs(ll u, ll time)
{if (u >= n)return true;// 已经有n架飞机降落,顺序合法// 遍历所有飞机,考虑它们的降落顺序for (int i = 0; i < n; i++){if (!st[i])// 如果没有降落{st[i] = true;if (p[i].t + p[i].d < time)// 如果当前时间超过了飞机的最晚降落时间{//回溯,回溯到DFS之前的状态。st[i] = false;return false;}ll t = max(time, p[i].t) + p[i].l;if (dfs(u + 1, t))return true;//回溯,回溯到DFS之前的状态。st[i] = false;}}return false;
}void solve()
{cin >> n;for (int i = 0; i < n; i++)// 读入每架飞机的信息cin >> p[i].t >> p[i].d >> p[i].l;if (dfs(0, 0))cout << "YES" << endl;elsecout << "NO" << endl;for (int i = 0; i < n; i++)// 重置st数组,准备下一组数据st[i] = false;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);int t = 1;cin >> t;while (t--)solve();
}

二、全球变暖

题目描述

由于全球变暖导致海面上升,科学家预测未来几十年内,岛屿边缘的一个像素范围将会被海水淹没。具体来说,如果一块陆地像素(用“#”表示)与海洋像素(用“.”表示)相邻(即上下左右四个相邻像素中有海洋),这块陆地就会被淹没,变成海洋。给定一个N×N的海域照片,你需要计算根据科学家的预测,照片中会有多少岛屿被完全淹没。

输入描述

第一行包含一个整数N(1≤N≤1000),表示海域照片的尺寸。
接下来N行,每行包含N个字符,表示海域照片,其中“#”表示陆地,“.”表示海洋。照片保证第一行、第一列、第N行、第N列的像素都是海洋。

输出描述

输出一个整数,表示根据科学家的预测,会有多少岛屿被完全淹没。

样例输入

7
..##...
.###...
.#..#..
..####.
...#.#.
....###
.......

样例输出

1

解释

给定的海域照片中有两座岛屿,分别由"#"字符组成。根据科学家的预测,只有左边的岛屿会被完全淹没,因此输出为1。

思路:

初始化和输入

  • 定义了一个二维数组mp来存储给定的海域照片,其中“#”表示陆地,“.”表示海洋。
  • col数组用于记录每个像素点属于哪一个岛屿。
  • vis数组用于标记一个岛屿是否会被完全淹没。
  • 输入尺寸n和海域照片。
using ll = long long;
const int N = 1e3 + 5;int n, scc, // 尺寸和颜色编号
col[N][N];// 用于记录每个像素点属于哪一个岛屿
char mp[N][N];// 存储海域照片// 表示四个可能的移动方向:上,下,左,右
int dx[] = { 0,0,1,-1 };
int dy[] = { 1,-1,0,0 };bool vis[N * N];// 用于标记一个岛屿是否被完全淹没
  • 确定岛屿

for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)// 遍历每一个像素点{if (col[i][j] || mp[i][j] == '.') continue;scc++;       dfs(i, j);// 岛屿数量++ 开始DFS搜索}

首先,我们需要识别地图上所有的岛屿。这可以通过遍历整个照片来完成,每当我们遇到一个“#”(陆地)字符,我们就从这个点开始进行深度优先搜索(DFS),以找出这块陆地连接的所有部分,即一个完整的岛屿。在搜索过程中,我们将不同的岛屿染上不同的颜色,并将访问过的陆地标记为已访问,以避免重复计算。

  • DFS搜索判断岛屿是否会被淹没

对于每个岛屿,我们需要判断它是否会被完全淹没。这意味着我们需要检查岛屿的边缘是否与海洋相邻。如果岛屿的任何一部分位于边缘(即,与地图边缘的海洋相邻)或者有至少一个部分的上下左右四个方向中有一个是海洋,则这个岛屿将不会被完全淹没。否则,该岛屿将被视为会被完全淹没。

// 找出岛屿的范围
void dfs(int x, int y)
{col[x][y] = scc;// 标记该像素点属于当前岛屿for (int i = 0; i < 4; i++)// 遍历所有可能的移动方向{int nx = x + dx[i], ny = y + dy[i];// 计算新的位置if (col[nx][ny] || mp[nx][ny] == '.') continue;// 如果是访问过或者是海洋则跳过dfs(nx, ny);}
}
  • 使用dfs函数来找出每一个岛屿的范围。dfs函数通过递归地搜索每个陆地像素的上下左右四个相邻位置来实现,如果相邻位置也是陆地(“#”),则继续进行DFS搜索。
  • dfs的过程中,使用col数组来标记当前正在搜索的岛屿的所有像素点,即将这些点都标记为当前岛屿的编号scc
  • 通过dxdy数组来表示四个可能的移动方向(上、下、左、右),以便在DFS搜索中移动到相邻的像素点。
    for (int k = 0; k < 4; ++k)// 遍历四个方向{int x = i + dx[k], y = j + dy[k];if (mp[x][y] == '.') tag = false;// (x, y)处的像素是否被海洋淹没(全是陆地就不淹没)}
  •  计算被淹没的岛屿数量

  • 使用tag标记来表示当前检查的像素点是否会被淹没,即如果四个方向中有海洋,则tagfalse,表示该岛屿的这个部分会被淹没。
  • 对于每一个岛屿,如果其任何一个部分不会被淹没,则整个岛屿都不会被淹没。使用vis数组来标记这些情况。如果vis数组中对应的岛屿编号为false,则将其标记为true并增加ans计数器(记录不会被淹没的岛屿数量)。
if (tag)// 如果四个方向都不是海洋,则当前陆地像素点不会被淹没{if (!vis[col[i][j]]) ans++;// 如果这个岛屿还没有被计入被淹没的岛屿中, 完全被淹没的岛屿++vis[col[i][j]] = true;// 标记这个岛屿为被淹没}
  • 最后,输出scc - ans,即总岛屿数量减去不会被淹没的岛屿数量,得到的就是会被完全淹没的岛屿数量。
cout << scc - ans << '\n';
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e3 + 5;int n, scc, // 尺寸和颜色编号
col[N][N];// 用于记录每个像素点属于哪一个岛屿
char mp[N][N];// 存储海域照片// 表示四个可能的移动方向:上,下,左,右
int dx[] = { 0,0,1,-1 };
int dy[] = { 1,-1,0,0 };bool vis[N * N];// 用于标记一个岛屿是否被完全淹没// 找出岛屿的范围
void dfs(int x, int y)
{col[x][y] = scc;// 标记该像素点属于当前岛屿for (int i = 0; i < 4; i++)// 遍历所有可能的移动方向{int nx = x + dx[i], ny = y + dy[i];// 计算新的位置if (col[nx][ny] || mp[nx][ny] == '.') continue;// 如果是访问过或者是海洋则跳过dfs(nx, ny);}
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >> n;//读入尺寸for (int i = 1; i <= n; i++)cin >> mp[i] + 1;// 读入海域照片数据// 从这一行的第二个元素开始读取输入for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)// 遍历每一个像素点{if (col[i][j] || mp[i][j] == '.') continue;scc++;       dfs(i, j);// 岛屿数量++ 开始DFS搜索}int ans = 0;// 用于记录被完全淹没的岛屿数量for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++){if (mp[i][j] == '.') continue;// 如果是海洋,则跳过bool tag = true;// 标记是否会被淹没for (int k = 0; k < 4; ++k)// 遍历四个方向{int x = i + dx[k], y = j + dy[k];if (mp[x][y] == '.') tag = false;// (x, y)处的像素是否被海洋淹没(全是陆地就不淹没)}if (tag)// 如果四个方向都不是海洋,则当前陆地像素点不会被淹没{if (!vis[col[i][j]]) ans++;// 如果这个岛屿还没有被计入被淹没的岛屿中, 完全被淹没的岛屿++vis[col[i][j]] = true;// 标记这个岛屿为被淹没}}cout << scc - ans << '\n';// 输出未被淹没的岛屿数量return 0;
}

三、军训排队 

问题描述

数字王国开学了,它们也和我们人类一样有开学前的军训。现在一共有n名学生,每个学生有一个自己的名字(在数字王国里,名字就是一个正整数)。注意,学生们可能出现重名的情况。叛逆教官来看了之后感觉十分别扭,决定将学生重新分队。排队规则为:将学生分成若干队,每队里面至少有一个学生,且每队里面学生的名字不能出现倍数关系(注意,名字相同也算是倍数关系)。现在请你帮忙算算最少可以分成几队?

例如:有4名学生(2,3,4,4),最少可以分成(2,3)、(4)、(4)共3队。

输入格式

第一行包含一个正整数n,表示学生数量。

第二行包含n个由空格隔开的整数,第i个整数表示第i个学生的名字α。

输出格式

输出共1行,包含一个整数,表示最少可以分成几队。

样例输入

4

2 3 4 4

样例输出

3

(解释:如上所述,可以将4名学生分成(2,3)、(4)、(4)共3队,满足每队学生的名字之间不存在倍数关系。)

思路:

枚举最少队伍数量:
首先,我们可以从小到大枚举“最少队伍的数量”。这意味着,我们从最少的队伍数开始尝试,逐渐增加队伍数,直到找到一个可行的分组方案。

搜索合法性:
对于每一个枚举的队伍数量,我们需要判断在这个数量下是否可以成功分组。这可以通过搜索来实现。具体来说,我们确定总队伍数量后,对于每一个人(或元素),枚举他所属的队伍。这里,回溯法是一种非常有效的搜索技术。

剪枝策略:
在搜索过程中,为了提高效率,我们需要采用剪枝策略。一种常见的剪枝方法是,当某个人(或元素)尝试加入某个队伍时,我们立即检查这个队伍中是否已存在与该人具有某种特定关系(如倍系关系)的其他成员。如果存在这样的关系,我们就可以直接跳过当前尝试,因为它不可能导致一个有效的分组。

#include<bits/stdc++.h> 
using namespace std;const int N = 15; // 最大可能的队伍数目或学生数
int a[N], n; // a数组用来存储每个学生的名字,n表示学生的数量vector<int>v[N]; // 使用vector数组来表示每个队伍,存储队伍中学生的名字// dfs函数尝试将学生分配到不同的队伍中
bool dfs(int cnt, int dep) {// cnt表示当前尝试的队伍数量,dep表示当前处理到第几个学生if (dep == n + 1) {// 如果dep等于n+1,说明所有学生都已经被分配到队伍中return true;}for (int i = 1; i <= cnt; ++i) {// 遍历当前所有队伍,尝试将学生放入bool tag = true; // 用tag标记当前学生是否能放入队伍i中for (const auto& j : v[i]) {// 遍历队伍i中已经有的学生名字if (a[dep] % j == 0) {// 如果当前学生的名字是队伍中某学生名字的倍数tag = false; // 不能放入这个队伍break; // 停止遍历队伍}}if (!tag) continue; // 如果不能放入当前队伍,继续尝试下一个队伍v[i].push_back(a[dep]); // 将学生放入队伍iif (dfs(cnt, dep + 1)) return true; // 递归地尝试放置下一个学生v[i].pop_back(); // 如果不能成功放置,将学生从队伍i中移除}return false; // 如果所有队伍都不能放入当前学生,返回false
}
int main() {// 设置输入输出流以提高效率ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >> n; // 读入学生数量for (int i = 1; i <= n; i++) {cin >> a[i]; // 读入每个学生的名字}for (int i = 1; i <= n; i++) {// 从1个队伍尝试到n个队伍,找到最少可以分成的队伍数量if (dfs(i, 1)) {// 如果可以将所有学生分配到i个队伍中cout << i << '\n'; // 输出队伍的数量break;}}return 0; 
}

今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/286599.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qrcode插件-生成二维码

安装 yarn add qrcodejs2 --save npm install qrcodejs2 --save 使用 <template><div><div id"qrcodeImg"></div><!-- 创建一个div&#xff0c;并设置id --></div> </template> <script> import QRCode from q…

一篇文章,告别Flutter状态管理争论,问题和解决

起因 每隔一段时间&#xff0c;都会出现一个新的状态管理框架&#xff0c;最近在YouTube上也发现了有人在推signals, 一个起源于React的状态管理框架&#xff0c;人们总是乐此不疲的发明各种好用或者为了解决特定问题而产生的方案&#xff0c;比如Bloc, 工具会推陈出新&#x…

AI基础知识扫盲

AI基础知识扫盲 AIGCLangchain--LangGraph | 新手入门RAG&#xff08;Retrieval-Augmented Generation&#xff09;检索增强生成fastGPT AIGC AIGC是一种新的人工智能技术&#xff0c;它的全称是Artificial Intelligence Generative Content&#xff0c;即人工智能生成内容。 …

关于SpringMVC返回JSON中时间对象序列化的问题

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 首先要说明一点,SpringMVC进行JSON序列化处理时,使用的工具包是Jackson…

PointNet++论文复现(一)【PontNet网络模型代码详解 - 分类部分】

PontNet网络模型代码详解 - 分类部分 专栏持续更新中!关注博主查看后续部分! 分类模型的训练: ## e.g., pointnet2_ssg without normal features python train_classification.py --model pointnet2_cls_ssg --log_dir pointnet2_cls_ssg python test_classification.py…

云电脑火爆出圈,如何选择和使用?--腾讯云、ToDesk云电脑、青椒云使用评测和攻略

前言&#xff1a; Hello大家好&#xff0c;我是Dream。在当下&#xff0c;科技的飞速发展已经深入影响着我们的日常生活&#xff0c;特别是随着物联网的兴起和5G网络的普及&#xff0c;云计算作为一个重要的技术概念也逐渐走进了我们的视野。云计算早已不再是一个陌生的名词&am…

Mysql配置autocommit实际使用(慎用)

以下内容都是基于MySQL5.7。所有操作建议在MySQL客户端执行。navicat可能会先意想不到的问题 在导入频繁执行update、insert的时候&#xff0c;可以考虑关闭MySQL的自动提交 首先查询当前的状态 1开启 0关闭 select autocommit;设置本次连接关闭自动提交(如果需要永久关闭请修…

MySQL的安装

第一步 先下载MySQL 的压缩包 官网链接: 点击跳转MySQL官网 或者直接下载我所上传的压缩包MySQL8.0.20X64 第二步 将下载的文件解压&#xff0c;我的解压位置为E:\Program Files目录&#xff0c;大家可以根据自己的需求解压到不同位置。如下图 第三步 进入到E:\Program Files…

导演、音乐家、艺术家眼中的Sora第一印象

自从2月16日Sora发布的那个夜晚以来&#xff0c;多少人都在翘首以盼&#xff0c;期待能真正的用上Sora。但是OpenAI自己也懂&#xff0c;基于模型对齐问题、安全问题、推理算力问题等等&#xff0c;这玩意短期内&#xff0c;基本不可能放出来给大众用。当然了&#xff0c;等以后…

【Linux】进程的基本概念(进程控制块,ps命令,top命令查看进程)

目录 01.进程的基本概念 程序与进程 进程的属性 02.进程控制块&#xff08;PCB&#xff09; task_struct的内容分类 组织进程 03.查看进程 ps命令 top指令 在计算机科学领域&#xff0c;进程是一项关键概念&#xff0c;它是程序执行的一个实例&#xff0c;是操作系统的…

如何保证缓存与数据库的双写一致性?

如何保证缓存与数据库的双写一致性&#xff1f; 概述同步策略更新缓存还是删除缓存&#xff1a;先操作数据库还是缓存&#xff1a;案例一、先删除缓存&#xff0c;在更新数据库案例二 先操作数据库&#xff0c;再删除缓存 延时双删策略&#xff08;不推荐&#xff09;使用分布式…

《数据安全技术 数据分类分级规则》及典型行业标准指南要点提炼

数据分类分级发布新国标 千呼万唤&#xff0c;国家标准GB/T 43697-2024《数据安全技术 数据分类分级规则》于3月21日正式发布。作为全国网络安全标准化技术委员会更名后&#xff0c;发布的第一部以“数据安全技术”命名的国家标准&#xff0c;《数据安全技术 数据分类分级规则…

K8s+Nacos实现应用的优雅上下线【生产实践】

文章目录 前言一、环境描述二、模拟请求报错三、配置优雅上下线1.修改nacos配置2.修改depolyment配置3.重新apply deployment后测试4.整体(下单)测试流程验证是否生效 四、期间遇到的问题 前言 我们在使用k8s部署应用的时候&#xff0c;虽然k8s是使用滚动升级的&#xff0c;先…

【CXL协议-事务层之CXL.cache (3)】

3.2 CXL.cache 3.2.1 概述 CXL.cache 协议将设备和主机之间的交互定义为许多请求&#xff0c;每个请求至少有一个关联的响应消息&#xff0c;有时还有数据传输。 该接口由每个方向的三个通道组成&#xff1a; 请求、响应和数据。 这些通道根据其方向命名&#xff0c;D2H&…

【笔记】深入理解JVM机制

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 JVM 运⾏流程图 JVM 中内存区域划分 方法区 / 元数据区 堆 栈 程序计数器 本地方法栈 内存区域总结 JVM 中类加载过程 …

Go第三方框架--gin框架(一)

序言 Gin框架作为go语言使用最多的web框架&#xff0c;以其快速的响应速度和对复杂http路由配置的支持受到程序员和媛们的喜爱&#xff0c;几乎统治了web市场。但作为一名合格的程序员&#xff0c;要知其然更要知其所以然&#xff0c;不然八股文背的也没有啥意思。本着这个原则…

【Java程序设计】【C00368】基于(JavaWeb)Springboot的箱包存储系统(有论文)

TOC 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击卡片…

【MySQL数据库】数据类型和简单的增删改查

目录 数据库 MySQL的常用数据类型 1.数值类型&#xff1a; 2.字符串类型 3.日期类型 MySQL简单的增删改查 1.插入数据&#xff1a; 2.查询数据&#xff1a; 3.修改语句&#xff1a; 4.删除语句&#xff1a; 数据库 平时我们使用的操作系统都把数据存储在文件中&#…

3.3 数据定义 数据库与系统概论

目录 3.3.1 模式的定义与删除 1. 定义模式 2. 删除模式 CASCADE&#xff08;级联&#xff09; RESTRICT&#xff08;限制&#xff09; 3.3.2 基本表的定义、删除与修改 表的定义 2.数据类型 3. 模式与表 4. 修改基本表 5. 删除基本表 3.3.3 索引的建立与删除 1. …

如何备考2024年AMC10:吃透2000-2023年1250道真题(限时免费送)

我们今天继续来随机看5道AMC10真题&#xff0c;以及详细解析&#xff0c;这些题目来自1250道完整的官方历年AMC10真题库。通过系统研究和吃透AMC10的历年真题&#xff0c;参加AMC10的竞赛就能拿到好名次。即使不参加AMC10竞赛&#xff0c;掌握了这些知识和解题思路后初中和高中…