[蓝桥杯] 递归与递推习题训练

文章目录
一、递归实现指数型枚举
1、1 题目描述
1、2 题解关键思路与解答
二、递归实现排列型枚举
2、1 题目描述
2、2 题解关键思路与解答
三、递归实现组合型枚举
3、1 题目描述
3、2 题解关键思路与解答
四、带分数
4、1 题目描述
4、2 题解关键思路与解答
五、费解的开关
5、1 题目描述
5、2 题解关键思路与解答
六、总结
标题:蓝桥杯——递归与递推习题训练
作者:@Ggggggtm
寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景
蓝桥杯比赛只有四十天左右啦,最近会按照模块更新一些有关蓝桥杯算法题。学习算法不仅仅是为了参见比赛,更是以后找工作的一个敲门砖。废话不多说,我们直接看题。
一、递归实现指数型枚举
1、1 题目描述
题目来源:《算法竞赛进阶指南》
题目难度:简单
题目描述:
从 1∼n这 n个整数中随机选取任意多个,输出所有可能的选择方案。
输入格式:
输入一个整数 n。
输出格式:
每行输出一种方案。
同一行内的数必须升序排列,相邻两个数用恰好 1个空格隔开。
对于没有选任何数的方案,输出空行。
本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。
数据范围:
1≤ n≤ 15
输入样例:
3输出样例:
3 2 2 3 1 1 3 1 2 1 2 3
1、2 题解关键思路与解答
由于上述题目是要求递归,我们可以通过开一个数组纪录是否选择该数组(0表示还没对该数字进行操作,1表示选择该数字,2表示不选择该数字)。这样通过递归,我们就可以很好的枚举出每一种情况。我们结合代码一起理解一下。
#include<iostream>
using namespace std;const int N=16;int n;
int state[N];
void dfs(int a)
{if(a>n){for(int i=1;i<=n;i++){if(state[i]==1)printf("%d ",i);}puts("");return;}state[a]=2;dfs(a+1);//恢复现场state[a]=0;state[a]=1;dfs(a+1);//恢复现场state[a]=0;
}
int main()
{cin>>n;dfs(1);return 0;
}
二、递归实现排列型枚举
2、1 题目描述
题目来源:《算法竞赛进阶指南》
题目难度:简单
题目描述:
把 1∼n这 n个整数排成一行后随机打乱顺序,输出所有可能的次序。
输入格式:
一个整数 n。
输出格式:
按照从小到大的顺序输出所有方案,每行 1 个。
首先,同一行相邻两个数用一个空格隔开。
其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面。
数据范围:
1≤n≤9
输入样例:
3输出样例:
1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
2、2 题解关键思路与解答
这个题的关键就在于是排列。通过递归枚举的方法实现排列,我们需要开两个数组:一个数组是记录还数字是否被使用过(0是未被使用,1是已经使用),另一个数组记录所排序的数字。题目中还要求了字典序,正常从小到大递归就已经是字典序较小的排在前面。我们直接看代码。
#include<iostream>
using namespace std;const int N=10;int n;
int state[N];
int used[N];
void dfs(int a)
{if(a>n){for(int i=1;i<=n;i++)printf("%d ",state[i]);puts("");return;}for(int i=1;i<=n;i++){if(used[i]==0){state[a]=i;used[i]=1;dfs(a+1);used[i]=0;}}
}
int main()
{cin>>n;dfs(1);return 0;
}
三、递归实现组合型枚举
3、1 题目描述
题目来源:《算法竞赛进阶指南》
题目难度:简单
题目描述:
从 1∼n 这 n个整数中随机选出 m个,输出所有可能的选择方案。
输入格式:
两个整数 n,m,在同一行用空格隔开。
输出格式:
按照从小到大的顺序输出所有方案,每行 1 个。
首先,同一行内的数升序排列,相邻两个数用一个空格隔开。
其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如
1 3 5 7排在1 3 6 8前面)。数据范围:
n>0,
0≤m≤n,
n+(n−m)≤25输入样例:
5 3输出样例:
1 2 3 1 2 4 1 2 5 1 3 4 1 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5
3、2 题解关键思路与解答
组合与排列十分相似,但又有些不同。组合特殊的是 1,2,3 与 2,1,3 与 3,2,1相同的,算是一种组合类型。题目中要求的同一行内的数升序排列。怎么定义升序呢?我们可以人为的选数字为升序。我们可以把整体的升序看成局部的升序,只要是满足后一个数比前一个数大即可。
#include<iostream>
#include<cstdio>
#include<cstring>using namespace std;int n,m;const int N=26;int way[N];
void def(int a,int start)
{if(a-1+n-start+1<m) //剪枝return;if(a==m+1){for(int i=1;i<=m;i++){printf("%d ",way[i]);}printf("\n");return;}for(int i=start;i<=n;i++){way[a]=i;def(a+1,i+1);}
}
int main()
{cin>>n>>m;def(1,1);return 0;
}
四、带分数
4、1 题目描述
题目来源:第四届蓝桥杯省赛C++B/C组
题目难度:中等
题目描述:
100可以表示为带分数的形式:100=3+69258 / 714
还可以表示为:100=82+3546 / 197
注意特征:带分数中,数字 1∼9 分别出现且只出现一次(不包含 0)。
类似这样的带分数,100 有 11 种表示法。
输入格式:
一个正整数。
输出格式:
输出输入数字用数码 1∼9不重复不遗漏地组成带分数表示的全部种数。
数据范围:
1≤N<106
输入样例1:
100输出样例1:
11输入样例2:
105输出样例2:
6
4、2 题解关键思路与解答
我们可以把带分数的形式看成一个公式:n = a + b / c 。也就是a、b和c 的数字 中1∼9 分别出现且只出现一次。那我们就可以想枚举a和c的情况,然后通过公式 b = c*n-c*a 计算出b的值。再把b的每一位拿出来看看时候符合题目所要求的情况。我们直接结合代码一起理解一下。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>using namespace std;const int N=12;int n,ans;
bool st[N],backup[N];bool check(int a,int c)
{long long b=n*(long long)c-a*c;memcpy(backup,st,sizeof(st));while(b){int x=b%10;b/=10;if(!x || backup[x])return false;backup[x]=true;}for(int i=1;i<=9;i++){if(!backup[i])return false;}return true;
}
void dfs_c(int u,int a,int c)
{if(u>9)return;if(check(a,c))ans++;for(int i=1;i<=9;i++){if(!st[i]){st[i]=true;dfs_c(u+1,a,c*10+i);st[i]=false;}}
}
void dfs_a(int u,int a)
{if(a>=n)return;if(a)dfs_c(u,a,0);for(int i=1;i<=9;i++){if(!st[i]){st[i]=true;dfs_a(u+1,a*10+i);st[i]=false;}}
}
int main()
{cin>>n;dfs_a(0,0);cout<<ans<<endl;return 0;
}
五、费解的开关
5、1 题目描述
题目来源:《算法竞赛进阶指南》
题目难度:中等
题目描述:
你玩过“拉灯”游戏吗?
25 盏灯排成一个 5×5 的方形。
每一个灯都有一个开关,游戏者可以改变它的状态。
每一步,游戏者可以改变某一个灯的状态。
游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。
我们用数字 1 表示一盏开着的灯,用数字 0 表示关着的灯。
下面这种状态:
10111 01101 10111 10000 11011在改变了最左上角的灯的状态后将变成:
01111 11101 10111 10000 11011再改变它正中间的灯后状态将变成:
01111 11001 11001 10100 11011给定一些游戏的初始状态,编写程序判断游戏者是否可能在 6 步以内使所有的灯都变亮。
输入格式:
第一行输入正整数 n,代表数据中共有 n 个待解决的游戏初始状态。
以下若干行数据分为 n 组,每组数据有 5 行,每行 5 个字符。
每组数据描述了一个游戏的初始状态。
各组数据间用一个空行分隔。
输出格式:
一共输出 n 行数据,每行有一个小于等于 66 的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。
对于某一个游戏初始状态,若 6 步以内无法使所有灯变亮,则输出 −1。
数据范围:
0<n≤500
输入样例:
3 00111 01011 10001 11010 1110011101 11101 11110 11111 1111101111 11111 11111 11111 11111输出样例:
3 2 -1
5、2 题解关键思路与解答
由于每个灯是数字 1 表示一盏开着的灯,用数字 0 表示关着的灯,我们就一行一行就行看。一行有五个灯,我们把代表灯的状态的数字看作一个数的二进制位。也就是一行有32种情况。整体的思路就是下一行影响上一行,我们需要做的是首先枚举第一行的32种情况,接着调整完前四行,最后看第五行是否为全亮即可。我们直接看代码:
#include<iostream>
#include<cstdio>
#include<cstring>using namespace std;const int N=6;
char g[N][N],backup[N][N];
int dx[5]={-1,0,1,0,0},dy[5]={0,0,0,-1,1};void turn(int x,int y)
{for(int i=0;i<5;i++){int a=x+dx[i],b=y+dy[i];if(a<0 || a>4 || b<0 || b>4)continue;g[a][b]^=1;}
}
int main()
{int n;cin>>n;while(n--){int res=10;for(int i=0;i<5;i++)cin>>g[i];for(int op=0;op<32;op++){int step=0;memcpy(backup,g,sizeof(g));for(int i=0;i<5;i++){if(op>>i&1){step++;turn(0,i);}}for(int i=0;i<4;i++){for(int j=0;j<5;j++){if(g[i][j]=='0'){step++;turn(i+1,j);}}}bool back=false;for(int i=0;i<5;i++){if(g[4][i]=='0'){back=true;break;}}if(!back)res=min(res,step);memcpy(g,backup,sizeof(g));}if(res>6)res=-1;cout<<res<<endl;}return 0;
}
六、总结
通过上面的习题练习,我们发现用递归去枚举也很简单。同时,我们也要掌握上面的递归枚举的思路和方法。在很多情况下,我们可以多开数组来进行记录或者操作,会给我们带来很大的便利。
递归与递推的练习就到这里,希望以上内容对你有所帮助。
相关文章:
[蓝桥杯] 递归与递推习题训练
文章目录 一、递归实现指数型枚举 1、1 题目描述 1、2 题解关键思路与解答 二、递归实现排列型枚举 2、1 题目描述 2、2 题解关键思路与解答 三、递归实现组合型枚举 3、1 题目描述 3、2 题解关键思路与解答 四、带分数 4、1 题目描述 4、2 题解关键思路与解答 五、费解的开关…...
领航智能汽车信息安全新征程 | 云驰未来乔迁新址
2月20日,在北京朝阳百子湾东朝时代创意园,云驰未来迎来乔迁之喜,智能汽车和自动驾驶领域的行业领导、合作伙伴与客户、投资人及媒体嘉宾齐聚现场,共同见证云驰未来迈上新的发展征程。 作为中国智能网联汽车和自动驾驶信息安全行业…...
Kaldi语音识别技术(七) ----- 训练GMM
Kaldi语音识别技术(七) ----- GMM 文章目录Kaldi语音识别技术(七) ----- GMM训练GMMtrain_mono.sh 用于训练GMM训练GMM—生成文件训练GMM—final模型查看训练GMM—final.occs查看训练GMM—对齐信息查看训练GMM—fsts.*.gz查看训练GMM—tree决策树查看align_si.sh 用于对齐训练G…...
Java 集合基础
文章目录一、集合概念二、ArrayList1. 构造方法和添加方法2. 常用方法三、案例演示1. 存储字符串并遍历2. 存储学生对象并遍历3. 键盘录入学生对象并遍历一、集合概念 编程的时候如果要存储多个数据,使用长度固定的数组存储格式,不一定满足我们的需要&a…...
Day896.MySql的kill命令 -MySQL实战
MySql的kill命令 Hi,我是阿昌,今天学习记录的是关于MySql的kill命令的内容。 在 MySQL 中有两个 kill 命令: 一个是 kill query 线程 id,表示终止这个线程中正在执行的语句;一个是 kill connection 线程 id&#…...
L2-010 排座位
布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席。 输入格式࿱…...
C++的完美讲解,还不快来看看?
目录 简介: 创建C程序: Windows编译简介: Hello,C World! 简介: C融合了3中不同的编程传统:C语言代表的过程性传统、C在C语言基础上添加的类代表的面向对象语言的传统以及C模板支持的通用编程传统。一般来说,计算机语言…...
C语言学习_DAY_5_循环结构while和for语句【C语言学习笔记】
高质量博主,点个关注不迷路🌸🌸🌸! 目录 I. 案例引入 II. while语句 III. do while语句 IV. for语句 前言: 书接上回,判断结构已经解决,接下来是另一种很重要的结构:循环结构的实…...
JavaScript高级程序设计读书分享之4章——4.3垃圾回收
JavaScript高级程序设计(第4版)读书分享笔记记录 适用于刚入门前端的同志 4.3.3 性能 垃圾回收程序会周期性运行,如果内存中分配了很多变量,则可能造成性能损失,因此垃圾回收的 时间调度很重要。尤其是在内存有限的移动设备上,垃圾…...
Java线程的6 种状态
Java 线程的状态 Java线程有六种状态: 初始(NEW)、运行(RUNNABLE)、阻塞(BLOCKED)、 等待(WAITING)、超时等待(TIMED_WAITING)、终止(…...
5年测试在职经验之谈:3年手工测试、2年的自动化测试,从入门到不可自拔...
毕业3年了,学的是环境工程专业,毕业后零基础转行做软件测试。 已近从事测试行业8年了,自己也从事过3年的手工测试,从事期间越来越觉得如果一直在手工测试的道路上前进,并不会有很大的发展,所以通过自己的努…...
QHash-官翻
QHash 类 template <typename Key, typename T> class QHash QHash 类是一种模板类,提供基于哈希表的字典类结构。更多内容… 头文件:#include <QHash>qmake:QT core派生类:QMultiHash 所有成员列表,包括继承的成员废弃的成员 注意&…...
MYSQL 配置优化
max_connections 允许客户端并发连接的最大数量,默认值是151。 show status like %connections%; 设置参数值应大于Max_used_connections。如果使用连接池,可参考连接池的最大连接数和每个连接池的数量作为参考设置 innodb_buffe_pool_instances Inno…...
多 态
1多态的基本概念多态是C面向对象三大特性之一多态分为两类静态多态: 函数重载和运算符重载属于静态多态,复用函数名动态多态: 派生类和虚函数实现运行时多态静态多态和动态多态区别:静态多态的函数地址早绑定–--编译阶段确定函数地址动态多态的函数地址晚绑定–--运…...
Java集合
集合、数组都是对多个数据进行存储操作的结构,简称java容器 (此时的存储,主要指的是内存层面的存储,不涉及持久化的存储) 数组存储的特点: 一旦初始化,其长度就确定了。数组一旦定义好&#x…...
高校借力泛微,搭建一体化、流程化的内控管理平台
财政部《行政事业单位内部控制规范(试行)》中明确规定:行政事业单位内部控制是指通过制定制度、实施措施和执行程序,实现对行政事业单位经济活动风险的防范和管控,包括对其预算管理、收支管理、采购管理、资产管理、建…...
使用人工智能赚钱的方式,行业领域有哪些?
使用人工智能赚钱的方式,行业领域有哪些?不少于2000字。 一、人工智能的应用领域 1、金融服务:金融服务行业是人工智能应用的领域之一,它可以帮助银行、信用卡公司等金融机构实现快速、有效的贷款审批,以及客户分析、…...
【数组中重复的数字】-C语言-题解
原题链接:数组中重复的数字 一、描述: 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数…...
C++调用Python脚本进行18次循环操作后,脚本不执行
C调用Python脚本进行18次循环操作后,脚本不执行 现象: 发送端接收端 从第二张图中可以看出,python脚本卡在’[parkin_debug] 6’与’[parkin_debug] 7’之间 该测试经过多次反复测试,均在第18次循环执行时,出现上述问…...
字节10年架构师职业发展经历,助你做好职业规划
一直以来程序员这一职业都给人高薪资的印象,近年来随着互联网行业的快速发展,程序员更是人满为患,然而很多人关注的却是程序员的薪资,而非职业本身。 一批批程序员进入工作岗位,但是很多人并没有对自己的职业生涯有清…...
AAC编码详解
嵌入式音视频开发——AAC编码 1. AAC 编码概述 在嵌入式音视频开发中,AAC(Advanced Audio Coding,高级音频编码)是一种非常常见的有损音频压缩技术,广泛应用于手机、机顶盒、车机、智能摄像头、会议终端、对讲设备以及…...
手把手教你学Simulink——基于Simulink的模型预测控制(MPC)PFC整流器快速动态响应
目录 手把手教你学Simulink ——基于Simulink的模型预测控制(MPC)PFC整流器快速动态响应 一、问题背景 二、系统建模与控制目标 1. 单相 Boost PFC 拓扑 2. 动态方程(αβ 静止坐标系) 3. 控制目标 三、有限控制集 MPC(FCS-MPC)设计 1. 预测模型(离散化) 2. 代…...
Hunyuan-MT-7B开源镜像免配置部署:像素语言传送门一键启动教程(含GPU适配)
Hunyuan-MT-7B开源镜像免配置部署:像素语言传送门一键启动教程(含GPU适配) 1. 项目介绍 像素语言跨维传送门是一款基于Tencent Hunyuan-MT-7B大模型构建的创新翻译工具。它将传统翻译体验重构为16-bit像素冒险风格,让语言转换变…...
【AI+实战】零基础部署私人ChatGPT网站:从NextChat到功能定制
1. 为什么你需要一个私人ChatGPT网站? 最近两年AI对话机器人的火爆程度,相信大家都有目共睹。但你是否遇到过这些问题:公共平台经常排队、担心隐私泄露、或者想要定制专属功能?这就是为什么越来越多的个人和小团队开始搭建自己的C…...
多宽带联网(五) OpenWrt中MWAN3高级策略分流实战(游戏加速、视频优化场景)
1. MWAN3策略分流的核心价值 家里拉了两条宽带却发现刷视频卡、打游戏延迟高?这种情况我遇到过太多次了。去年给朋友家调试网络时,他同时接了电信和联通两条200M宽带,但看4K视频还是缓冲,玩外服游戏延迟总在200ms以上。后来用Open…...
FPGA密码锁设计避坑指南:状态机划分、时序约束与安全逻辑的那些事儿
FPGA密码锁设计避坑指南:状态机划分、时序约束与安全逻辑的那些事儿 在FPGA开发领域,密码锁设计看似简单,实则暗藏玄机。许多工程师在完成基础功能后,往往会在状态机划分、时序约束和安全逻辑等环节踩坑。本文将结合实战经验&…...
MiniCPM-V-2_6嵌入式AI应用实战:STM32F103C8T6边缘推理集成
MiniCPM-V-2_6嵌入式AI应用实战:STM32F103C8T6边缘推理集成 最近几年,AI模型越来越“小”,开始往各种硬件设备里钻。你可能听说过在手机、树莓派上跑AI,但有没有想过,在一块只有指甲盖大小、主频72MHz、内存才20KB的S…...
忍者像素绘卷参数详解:如何通过提示词触发‘火之意志’专属风格权重
忍者像素绘卷参数详解:如何通过提示词触发火之意志专属风格权重 1. 认识忍者像素绘卷 忍者像素绘卷是一款基于Z-Image-Turbo深度优化的图像生成工具,它将传统忍者文化与16-Bit复古游戏美学完美结合。这款工具特别适合创作具有热血动漫风格的像素艺术作…...
QT6.5串口编程第一步:用CMakeLists.txt引入SerialPort模块的避坑指南
QT6.5串口编程避坑指南:CMakeLists.txt配置全解析 当你满怀期待地在QT6.5项目中引入串口通信功能,却在编译时遭遇"找不到QtSerialPort"的红色错误提示,这种挫败感我深有体会。作为一位经历过无数次类似"战斗"的开发者&am…...
[模电]从PN结到实用电路:二极管的深度解析与设计指南
1. PN结:二极管的物理基础 想象一下把一块P型半导体和N型半导体紧密贴合在一起,就像把两块不同颜色的橡皮泥揉捏在一起。P型半导体里充满了带正电的"空穴"(可以理解为缺少电子的位置),而N型半导体则富含自由…...
