文章目录

  • 带分数
    • 解题思路
    • AC代码
  • 走迷宫
      • 题目描述
      • 输入描述
      • 输出描述
      • 输入输出样例
        • 示例 1
    • 解题思路
  • 蓝桥幼儿园
    • 解题思路
    • AC代码
  • 跳石头
    • 题目解析
    • AC代码
    • AC代码2
    • 写在最后

往期蓝桥杯真题解析

【蓝桥杯冲刺 day10】题目全解析 — 难题突破

【蓝桥杯冲刺 day8】题目全解析 —附上LeetCode 每日一题

【蓝桥杯冲刺 day7】 题目全解析 — 附上LeetCode周赛 银联-03. 理财产品

【蓝桥杯冲刺 day4】题目全解析 — 每日刷题解析

【蓝桥杯】算法训练 无聊的逗

【蓝桥杯】算法提高 打包

【蓝桥杯】算法提高 学生节


引言

Hello大家好啊,我是秋刀鱼,今天因为时间比较宽裕所以又给大家出题解啦,希望能够得到大家的支持!

今天的题目不算太难(可能是昨天太难了),但是题目中涉及到的知识点还是很重要的,包括全排列、并查集、BFS搜索、贪心与二分算法,而且每一道题都是细节满满,希望你能耐心看完本篇题解,相信你一定能有所收获。


带分数

题目传送门

问题描述

100 可以表示为带分数的形式:100 = 3 + 69258 / 714。

还可以表示为:100 = 82 + 3546 / 197。

注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。

类似这样的带分数,100 有 11 种表示法。

输入格式

从标准输入读入一个正整数N (N<1000*1000)

输出格式

程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。

注意:不要求输出每个表示,只统计有多少表示法!

样例输入1

100

样例输出1

11

样例输入2

105

样例输出2

6

解题思路

这道题的核心思路是全排列,既然要是 1~9 的数字不能重复出现,那么将 1~9 的数字全排列并存储与数组中。,题目要求满足的式子:a+b/c=targeta+b/c = targeta+b/c=target,那么定义两个指针idx1idx2将全排列中的数据进行分割,分割3个数字 a,b,c:

[0,idx1) a
[idx1,idx2] b
(idx2,n) c

根据索引范围可以得到这三个数的具体值,将a+b/c的值与target进行一个比较,就可以获得答案。

AC代码

#include <iostream>
#include <cstring>
using namespace std;
int value[10];
int ans = 0;
int target;
// 获取[l,r]索引位置上的数
int getValue(int l, int r) {int ret = 0;while (l <= r) {ret *= 10;ret += value[l];++l;}return ret;
}
void judge() {// [0,idx1) 第一个数// [idx1,idx2] 第二个数// (idx2,n) 第三个数int idx1, idx2;for (idx1 = 0; idx1 <= 10; ++idx1) {for (idx2 = idx1; idx2 < 10; ++idx2) {int value1 = getValue(0, idx1 - 1);int value2 = getValue(idx1, idx2);int value3 = getValue(idx2 + 1, 8);if (value3 == 0||value2%value3!=0) {continue;}if (value1+value2/value3==target){++ans;}}}
}
// 全排列递归
void dfs(int low,int high) {if (low==high) {judge();return;}for (int i = low; i < high; ++i) {swap(value[i], value[low]);dfs(low + 1, high);swap(value[i], value[low]);}
}
int main()
{cin >> target;memset(value, 0, sizeof(value));for (int i = 0; i < 9; ++i) {value[i] = i + 1;}dfs(0, 9);cout << ans;return 0;
}

走迷宫

题目传送门

题目描述

给定一个 N×M* 的网格迷宫 GG 的每个格子要么是道路,要么是障碍物(道路用 1 表示,障碍物用 0 表示)。

已知迷宫的入口位置为 (x1,y1),出口位置为 (x2,y2)。问从入口走到出口,最少要走多少个格子。

输入描述

输入第 11 行包含两个正整数 N*,M,分别表示迷宫的大小。

接下来输入一个 N×M 的矩阵。若 i*,*j=1 表示其为道路,否则表示其为障碍物。

最后一行输入四个整数 x_1,y_1,x_2,y_2x1,y1,x2,y2,表示入口的位置和出口的位置。

输出描述

输出仅一行,包含一个整数表示答案。

若无法从入口到出口,则输出 -1−1。

输入输出样例

示例 1

输入

5 5
1 0 1 1 0
1 1 0 1 1
0 1 0 1 1
1 1 1 1 1
1 0 0 0 1
1 1 5 5

输出

8

解题思路

基础的一道BFS搜索问题,搜索最短路径使用宽度优先遍历准没有错。

#include <iostream>
#include <cstring>
#include <queue>
#define pii pair<int,int>
#define M 110
using namespace std;
int points[M][M];
int n, m;
int ans = -1;
int directs[4][2]{ {1,0},{-1,0},{0,1},{0,-1} };
void bfs(int x, int y, int endX, int endY) {queue<pii>qu;qu.push({ x,y });// 保存步数int t = 0;while (qu.size()) {int len = qu.size();// 开启一轮遍历,一轮遍历中遍历到的点其走过的步数都是相同的,为tfor (int i = 0; i < len; ++i) {pii tmp = qu.front();qu.pop();// 遍历4个方向for (int k = 0; k < 4; ++k) {int nx = tmp.first + directs[k][0];int ny = tmp.second + directs[k][1];if (nx < 0 || ny < 0 || nx >= n || ny >= m || points[nx][ny] == 0) {continue;}if (nx == endX && ny == endY) {ans = t + 1;return;}qu.push({ nx,ny });points[nx][ny] = 0;}}++t;}
}
int main()
{cin.tie();cin >> n >> m;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {cin >> points[i][j];}}int x, y, endX, endY;cin >> x >> y >> endX >> endY;// 转换为数组索引--x; --y; --endX; --endY;bfs(x, y, endX, endY);cout << ans;return 0;
}

蓝桥幼儿园

题目传送门

题目描述
蓝桥幼儿园的学生是如此的天真无邪,以至于对他们来说,朋友的朋友就是自己的朋友。

小明是蓝桥幼儿园的老师,这天他决定为学生们举办一个交友活动,活动规则如下:

小明会用红绳连接两名学生,被连中的两个学生将成为朋友。

小明想让所有学生都互相成为朋友,但是蓝桥幼儿园的学生实在太多了,他无法用肉眼判断某两个学生是否为朋友。于是他起来了作为编程大师的你,请你帮忙写程序判断某两个学生是否为朋友(默认自己和自己也是朋友)

输入描述

输出描述
对于每个op=2的输入,如果z和y是朋友,则输出一行YES,否则输出一行NO。

输入输出样例
输入:

5 5
2 1 2
1 1 3
2 1 3
1 2 3
2 1 2
1
2
3
4
5
6
输出:

NO
YES
YES

解题思路

这道题算是并查集的模板题,如果没有学过的同学一定要预先学习一下并查集算法再作答。

本题如果直接使用并查集木板可能会超时,需要将关系图压缩优化一下。如果将关系比喻成一个多叉树,那么多叉树的高度决定了查询关系时的性能。

如果有如下关系:

fa[1]=fa[2]=fa[3]=fa[4]=4,那么当查询 1 结点的父节点时,需要遍历的次数为3,并且随着层数的增高遍历的次数也会增多,为了优化查找速度,可行的方法是在查询到 1 结点正在的父节点时 4 后,此时直接修改 1 号结点的关系将 1 号结点与 4 号结点绑定:

这样一来,下一次查询 1 号结点的父节点时,需要查询的次数减少为1次,极大地提高了查询性能。希望同学们能记住这种优化方法,只需要简单的一行代码能让性能提升不少!

AC代码

#include <iostream>
#define M 200010
using namespace std;
// 定义并查集类
class UnionFind {private:// 保存关系int fa[M];
public:UnionFind(int n) {for (int i = 1; i <= n; ++i) {fa[i] = i;}}int find(int idx) {if (fa[idx] == idx) {return idx;}// 改变关系,提高查询速度fa[idx]=find(fa[idx]);return fa[idx];}void merge(int n, int m) {int fa1 = find(n);int fa2 = find(m);if (fa1 == fa2) {return;}fa[fa1] = fa2;}
};
int main()
{int n, m;cin >> n >> m;UnionFind fa(n);for (int i = 1; i <= m; ++i) {int op, s1, s2;cin >> op >> s1 >> s2;if (op == 1) {fa.merge(s1, s2);}else {int fa1 = fa.find(s1);int fa2 = fa.find(s2);cout << (fa1 == fa2 ? "YES" : "NO") << endl;}}return 0;
}

跳石头

题目传送门

题目描述
一年一度的“跳石头”比赛又要开始了!
这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。
为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M 块岩石(不能移走起点和终点的岩石)。
输入描述:

输入文件第一行包含三个整数 L,N,M,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。
接下来 N 行,每行一个整数,第 i 行的整数 Di(0 < Di < L)表示第 i块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同一个位置。

输出描述:

输出文件只包含一个整数,即最短跳跃距离的最大值。

示例1
输入
复制

25 5 2
2
11
14
17
21

输出:

4

题目解析

总体解决思路是贪心+二分,不过相较于其他类似题目本题很具有代表性,需要考虑的细节也更多。

河道中在终点与起点之间分布着 N 块石头,终点与起点的距离为 L ,选手只能顺序地从起点跳往终点。委员会能在起点终点之间拿走 M 块石头,使得最短跳跃距离最大。

首先起点与终点的距离为L,也就是说如果拿走起点终点间的 N 块石头即 M = N,此时最短跳跃距离为 L ;那么我们可以大致推断,最短跳跃距离的最大值区间范围为:[0,L][0,L][0,L]。

对于 [0,L][0,L][0,L] 的区间取值,定义中间值为 mmm 为最短跳跃距离。现在从第一个石头出发,如果跳跃的距离小于 mmm ,我们就移除该石头。比较移除石头的次数 ttt 与最大移除次数 MMM ,如果 t<=Mt<=Mt<=M 表明该最大值下能够跳跃,缩小区间最终得到答案。

细节一:处理无限循环情况

假设区间缩小为 [2,3][2,3][2,3] ,得到中间值 m=2m = 2m=2 如果符合则 l = m,也就是说区间仍然是 [2,3][2,3][2,3] ,继续判断于是进入了死循环。为了避免死循环的出现,我们可以修改 mmm 中间值的获取方式,更改为:m=(l+r+1)/2

AC代码

#include <iostream>
using namespace std;
#define MAX 50010int stones[MAX];int L, N, M;
bool check(int gap) {int t = 0;int pre = 0;for (int i = 1; i <= N; ++i) {if (stones[i] - pre < gap) {++t;}else {pre = stones[i];}}return t <= M;
}
int main()
{cin >> L >> N >> M;for (int i = 1; i <= N; ++i) {cin >> stones[i];}int l, r;l = 0; r = L;while (l < r) {int m = (l + r + 1) / 2;if (check(m)) {l = m;}else {r = m - 1;}}cout << l;return 0;
}

细节二:处理终点问题

如上的代码确实能够AC,蓝桥杯官网中也能够通过,但是这就是这道题的最终解了吗?可能并不是。我之前有说过这道题细节满满,还有如下需要注意。

题目中有说到:组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)

注意到:起点与终点都是岩石,且就算是到达了中间的第 NNN 块石头,距离终点的第N+1N+1N+1 块石头也是有一段距离的,这一段距离当然也需要一次跳跃,这一次跳跃同样会影响到最短跳跃距离。因为最后的一块石头不能被拿走,因此最后一次的跳跃距离不管远近都不会影响组委会移动石头的次数,但是却能够直接影响答案。而上述的代码只考虑了[1,N][1,N][1,N] 块岩石的跳跃情况,没有判断最后一次跳跃。

正确的判断是,在退出check方法之前,判断 preprepre 与 终点的距离,如果这个距离本身就小于传入的最短跳跃距离,那么直接返回false。

AC代码2

#include <iostream>
using namespace std;
#define MAX 50010int stones[MAX];int L, N, M;
bool check(int gap) {int t = 0;int pre = 0;for (int i = 1; i <= N; ++i) {if (stones[i] - pre < gap) {++t;}else {pre = stones[i];}}// 获取最后一步的距离int red = L - pre;// 如果最后一步距离比 gap 更小直接返回if(red < gap){return false;}return t <= M;
}
int main()
{cin >> L >> N >> M;for (int i = 1; i <= N; ++i) {cin >> stones[i];}int l, r;l = 0; r = L;while (l < r) {int m = (l + r + 1) / 2;if (check(m)) {l = m;}else {r = m - 1;}}cout << l;return 0;
}

写在最后

代码、论述中有任何问题,欢迎大家指出,同时如果有任何疑问,也能够在评论区中留言,大家共同讨论共同进步!

如果觉得博主写的不错的话,可以点赞支持一下!ღ( ´・ᴗ・` )比心

【蓝桥杯真题训练 day14】今日四道真题全解析相关推荐

  1. 2020年 第11届 蓝桥杯 C/C++ B组 省赛真题详解及小结【第1场省赛2020.7.5】【Java版】

    蓝桥杯 Java B组 省赛真题详解及小结汇总[2013年(第4届)~2020年(第11届)] 注意:部分代码及程序 源自 蓝桥杯 官网视频(历年真题解析) 郑未老师. 2013年 第04届 蓝桥杯 ...

  2. 蓝桥杯省赛考点_【蓝桥杯单片机01】从历年决赛真题中寻找单片机常见的考点...

    [蓝桥杯单片机01]从历年决赛真题中寻找单片机常见的考点 广东职业技术学院  欧浩源 [第三届:门禁系统] 1.功能简述 "门禁系统"主要有两种工作模式: 模式1:7:00-22: ...

  3. 蓝桥杯java B组历年省赛真题汇总及题目详解

    蓝桥杯java B组历年省赛真题汇总及题目详解 2019年第十届蓝桥杯省赛真题详解 2018年第九届蓝桥杯省赛真题详解 2017年第八届蓝桥杯省赛真题详解 2016年第七届蓝桥杯省赛真题详解 2015 ...

  4. 2022年第十三届蓝桥杯比赛Java B组 【全部真题答案解析-第一部分】

    最近回顾了Java B组的试题,深有感触:脑子长时间不用会锈住,很可怕. 兄弟们,都给我从被窝里爬起来,赶紧开始卷!!! 2022年第十三届蓝桥杯Java B组(第一部分 A~F题) 目录 一.填空题 ...

  5. 蓝桥杯嵌入式第十届省赛真题

    蓝桥杯嵌入式第十届省赛真题 文章目录 蓝桥杯嵌入式第十届省赛真题 1.题目分析 2.项目结构 2.1数组思路 2.2Key_Flag控制对应逻辑 2.3KEY控制操作 1.题目分析 总的来说这题考点特 ...

  6. 第九届蓝桥杯JavaA组(2018年)省赛真题解析

    第九届蓝桥杯JavaA组(2018年)省赛真题解析 1.分数 1/1+1/2+1/4+1/8+1/16+- 每项是前一项的一半,如果一共有20项,求这个和是多少 结果用分数表示,类似: 3/2,当然这 ...

  7. 算法刷题系列(四)蓝桥杯python算法训练3(下)

    上一次的节点选择算法由于春节过年耽搁了,现在重新补上 上篇链接:算法刷题系列(四)蓝桥杯python算法训练3 - 经验教训 在纷繁复杂的使用了列表来暂存数据之后,发现其实可以利用笔者自己不太常用的字 ...

  8. 【蓝桥杯单片机第十二届国赛真题】

    [蓝桥杯单片机第十二届国赛真题] 文章目录 [蓝桥杯单片机第十二届国赛真题] 前言 一.真题 二.源码 前言 有幸进入国赛,为自己大学最后一个比赛画上完满的句号^@^ 下面为蓝桥杯单片机第十二届国赛程 ...

  9. 蓝桥杯Java大学C组近三年真题解析(三)——暴力、模拟题

    目录 第十届 求和 题目 题解 代码 矩形切割 题目 题解一 代码 代码 代码 题解二 代码 不同子串 题目 题解 代码 质数 题目 题解 代码 最大降雨量 题目 题解 代码 旋转 题目 题解 代码 ...

  10. 2020年第十一届蓝桥杯JavaC组(十月场)真题解析

    相关题目: 2016年第七届蓝桥杯真题解析JavaB组 2016年第七届蓝桥杯真题解析JavaC组 2017年第八届蓝桥杯真题解析JavaB组 2017年第八届蓝桥杯真题解析JavaC组 2018年第 ...

最新文章

  1. Aspose.Pdf 系列组件介绍
  2. JS获取div滚动条距离实现弹出标签位置动态移动
  3. mongodb php代码实例,MongoDB文档的更新(php代码实例)
  4. java基础第十四天_IO
  5. spring的Aop使用问题
  6. 廖雪峰python2.7教程_Python 2.7教程
  7. 日常生活收缩毛孔几个小妙招 - 健康程序员,至尚生活!
  8. C语言的“编译时多态”
  9. 一句话输出没有结束符的字符串
  10. tim怎么设置检测到新版本自动安装 tim安全自动更新的开启方法
  11. ESP8266:(2)获取时间和天气
  12. php markdown 电子书_PHP Markdown转PDF解决方案
  13. SCI从入门到精髓(三)——如何写出牛文章
  14. 常用函数的傅里叶变换对汇总
  15. word 此文件来自其它计算机,问题解决: 此文件来自其他计算机,可能被阻止以帮助保护该计算机/WORD在试图打开文件时遇到错误……...
  16. 科技巨头们在SaaS市场“雷声大雨点小”背后的症结
  17. 没有打不了的补丁切不了的面
  18. numpy.insert用法以及内插插0的方法
  19. PHP7.1 mcrypt_module_open() is deprecated
  20. 2022年武汉江岸区助企惠企政策汇总,附奖励补贴标准及申报条件

热门文章

  1. 转使用chrome命令行:disable
  2. 软件测试周刊(第08期):大过节的
  3. 6月3日 徒步虎跳峡——第一日
  4. 梦回大明湖畔遇见情窦初开的数据库,寻梦的开始,大明湖畔的夏雨荷-你在哪呢?
  5. 在github上写个人简历——最简单却又不容易的内容罗列
  6. js获取传统节假日_js判断节假日实例代码
  7. 软件工程的标准定义:什么是软件工程?
  8. cocoStudio工具的使用-----场景编辑器
  9. 模板库(七) - 字符串算法
  10. Javascript 面向对象编程(一):封装