寒假刷题-递归与递推

寒假刷题

92. 递归实现指数型枚举

image-20240115182149547

image-20240115182203169

解法1递归

使用递归对每一个坑位进行选择,每个坑位有两种选择,填或者不填,使用st数组来记录每个坑位的状态,u来记录已经有多少坑位有了选择。

image-20240115194744258

每个坑位有2钟选择,n个坑位的复杂度就是2的n次方。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 16;
int n;
int st[N];
void dfs(int u){if(u>n){for(int i = 1;i<=n;i++){if(st[i]==1)printf("%d ",i);}printf("\n");return;}st[u] = 1;dfs(u+1);st[u]=0;dfs(u+1);
}
int main(){scanf("%d",&n);dfs(1);return 0;
}

坑位的下标和这个坑位的数字是存在对应关系的,所以可以用一个u来控制递归的出口。我们只关心u位置是否有数字。
st[u] = 1;
dfs(u+1);
这两句相当于是将这个位置画对勾,然后跳到下一个位置进行选择
st[u]=0;
dfs(u+1);
这两句就是这个位置不填数进入下一轮,顺便回到dfs之前的状态。(这题无所谓)

解法2二进制压缩

1-n的所有整数排列的方案可以看作一个二进制序列,例如1-3的排列中,1 3就对应二进制101。有数字用1表示,没有数字用0表示。
1-n共有2的n次方钟方案。将所有方案数枚举,然后判断位数是否是1。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
int main()
{scanf("%d",&n);for(int i = 0;i < 1<<n;i ++){for(int j = 0;j < n;j ++){if(i >> j & 1)printf("%d ",j + 1);}printf("\n");}return 0;
}

94. 递归实现排列型枚举

这题就是一个全排列问题,和上一题的区别是很明显的。上一个的每个坑位的数字是固定的,可能有或没有,这个题的每个坑位的数是不固定的,且必须有。这个题需要使用st记录是否使用过。这个st和上一个题的st代表的意义不一样。

使用循环来进行dfs。循环从1开始,到n结束。通过st[i]可以知道数字i是否被使用过。如果没被使用过就使用i,然后进入下一层搜索。使用后一定要恢复现场。

image-20240115203650666

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 10;
int m,st[N],ans[N];
int n;
void dfs(int x)
{if(x > n) {for(int i = 1;i <= n;i ++){printf("%d ",ans[i]);}printf("\n");}for(int i = 1;i <=n;i ++){if(!st[i]){st[i] = 1;ans[x] = i;dfs(x+1);st[i] = 0;}}
}
int main()
{scanf("%d",&n);dfs(1);return 0;
}

717. 简单斐波那契

image-20240115205913881

使用递推来进行求解,通过观察可以发现这个数列的第n项只与n-1和n-2项有直接关系,所以使用三个变量a b fn,依次向后轮转。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){int n,fn;scanf("%d",&n);int a = 0,b = 1;for(int i = 1;i <= n;i ++){cout<<a<<" ";fn = a+b;a=b,b=fn;}
}

95. 费解的开关

image-20240115210215243

image-20240115210246482

image-20240115210312290

样例

image-20240115210417313

改变右上角的开关

image-20240115210526298

image-20240115210552593

两步即可让所有的灯变亮。

观察题意可以发现能影响灯本身的除了灯自己还有灯上下左右的灯,可以枚举第一行灯的32种按法,记得备份原数组,然后从第一行按到第四行,第i行可以通过第i+1行的灯来控制,遍历完第四行后,看看第五行还有没有灭的灯,如果有的话,那这个方案就是不可行的。因为没有第六行来控制第五行。如果第五行全亮,那这个就是可以调,判断一下和ans哪个更小。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 6;
char g[N][N],backup[N][N];
int n;
int dx[] = {1,-1,0,0,0};
int dy[] = {0,0,-1,1,0};
void turn(int x,int y){for(int i = 0;i < 5;i ++){int a = x + dx[i];int b = y + dy[i];if(a < 0 || b < 0 || a > 4 || b > 4)continue;g[a][b] ^= 1;}
}
int main(){scanf("%d",&n);while(n --){for(int i = 0;i < 5;i ++)scanf("%s",g[i]);int ans = 10;for(int op = 0;op < 32;op ++){memcpy(backup,g,sizeof g);int step = 0;for(int i = 0;i < 5;i ++){if(op >> i & 1){turn(0,i);step ++;}}for(int i = 0;i < 4;i ++){for(int j = 0;j < 5;j ++){if(g[i][j] == '0'){turn(i+1,j);step ++;}}}int drak = 0;for(int j = 0;j < 5;j ++){if(g[4][j] == '0'){drak = 1;break;}}if(drak == 0)ans = min(ans,step);memcpy(g,backup,sizeof g);}if(ans > 6)ans = -1;cout << ans <<endl;}return 0;
}

93. 递归实现组合型枚举

image-20240115212247504

image-20240115212301909

这题与全排列的区别就是字典序,只需要在判断是否使用过的时候加上一个判断,条件是当前的i是否大于ans数组的的最后一个元素,大于往里面添加,小于直接就跳过即可。ans数组初始化时要将元素变为-1,否则开头将无法添加。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int N = 26;
int n,m;
int ans[N] = {-1},st[N]={0};
void dfs(int c,int m){if(c > m){for(int i = 1;i <= m; i ++){cout << ans[i] << " ";}cout<<endl;return;}for(int i = c ;i <= n; i ++){if(!st[i]&&i > ans[c-1]){ans[c] = i;st[i] = 1;dfs(c + 1,m);st[i] = 0;}}
}
int main(){scanf("%d%d",&n,&m);dfs(1,m);return 0;
}

1209. 带分数

image-20240115212751409

image-20240115212807361

题意是
n = a + b / c n = a + b/c n=a+b/c
等式两边同时×c
c ∗ n = c ∗ a + b c*n = c*a+b cn=ca+b
通过dfs枚举a和c,然后计算出b,然后遍历st数组看看是否b的每一位都没有被用到。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 30;
int st[N],backup[N];
int n,ans,test;
bool check(int a,int c)
{long long b = (long long) n * c -a * c;if(!a || !b || !c)return false;memcpy(backup,st,sizeof st);while(b){int ge = b % 10;if(ge == 0 || backup[ge])return false;backup[ge] = 1;b /= 10;}for(int i = 1;i <= 9;i ++){if(backup[i] == 0) return false;}return true;
}
void dfs_c(int a,int c)
{if(check(a,c))ans ++;for(int i = 1; i <= 9; i ++){if(st[i] == 0){st[i] = 1;dfs_c(a,c*10 + i);st[i] = 0;}}
}
void dfs_a(int a)
{if(a > n)return;if(a)dfs_c(a,0);for(int i = 1;i <= 9; i ++){if(st[i] == 0){st[i] = 1;dfs_a(a*10 + i);st[i] = 0;}}
}
int main()
{scanf("%d",&n);dfs_a(0);cout << ans << endl;return 0;
}

116. 飞行员兄弟

和费解的开关类似,只不过这个题的数量比较下,所以枚举所有行的全部可能,共65536种,对每一种方案进行操作,记录最少的方案数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define x first
#define y second
using namespace std;typedef pair<int,int> PII;
const int N = 5;
char st[N][N],backup[N][N];
vector <PII> ans;
int get(int x,int y)
{return x*4 + y;
}
void turn(int x,int y)
{if(st[x][y]=='+')st[x][y]='-';else st[x][y]='+';
}
void turnall(int x,int y)
{for(int i = 0;i < 4;i ++){turn(x,i);turn(i,y);}turn(x,y);
}
int main()
{for(int i = 0;i < 4;i ++){scanf("%s",st[i]);}for(int i = 0;i < 1 << 16;i ++){vector <PII> step;memcpy(backup,st,sizeof st);for(int x = 0;x < 4;x ++){for(int y = 0;y < 4;y ++){if(i >> get(x,y) & 1){turnall(x,y);step.push_back({x,y});}}}int dark = 0;for(int x = 0;x < 4;x ++){for(int y = 0;y < 4;y ++){if(st[x][y]=='+'){dark = 1;break;}}}if(dark == 0){if(ans.empty()||ans.size() > step.size()) ans = step;}memcpy(st,backup,sizeof st);}cout << ans.size() << endl;for(auto p:ans){cout << p.x+1<<" "<<p.y+1<<endl;}return 0;
}

1208. 翻硬币

有个初始态有个结束态。将初始态与结束态一一对比,遇到不一样的就将移动次数加一并且变换硬币状态。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int ans;
string start,aim;
void turn(int i)
{if(start[i]=='*')start[i] = 'o';else start[i] = '*';
}
int main()
{cin>>start>>aim;for(int i = 0;i < start.size() - 1;i ++){if(start[i]!=aim[i])turn(i+1),ans++;}cout << ans <<endl;return 0;
}

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

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

相关文章

Java根据二叉树的先序和后序得到二叉树

一般情况下&#xff0c;我们会根据先序和后序写出二叉树&#xff0c;但是用代码怎末写呢&#xff1f; 例如&#xff1a; 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二…

pdf怎么查看?6个不能错过的软件!

PDF&#xff0c;作为一种常用的文件格式&#xff0c;已经成为了我们工作、学习中的必备工具。然而&#xff0c;对于许多新手来说&#xff0c;如何查看和编辑PDF文件却是一个不小的挑战。今天&#xff0c;我们就来为大家详细介绍一下如何查看和编辑PDF文件&#xff0c;以及一些必…

01_泛型

文章目录 泛型泛型类泛型接口泛型方法泛型的通配泛型的擦除 泛型 参数化类型。 泛型的好处&#xff1a; 省去了类型强转的麻烦&#xff08;比如&#xff1a;Object类、interface接口等都需要类型强转&#xff09;将运行期遇到的问题转移到了编译期 泛型类 所谓泛型类, 就是…

Android Dialog setCanceledOnTouchOutside失效,点击dialog外面不消失

前言&#xff1a;有一个需求需要点击dialog外面要消失&#xff0c;本来以为很简单结果设置了一直未生效 setCanceledOnTouchOutside(true); 问了半天chat-gpt4结果给的答案都不明显 查看代码发现设置了style&#xff0c;于是尝试去除这个style&#xff0c;结果点击setCancele…

【c++】——栈or队列or优先级队列

目录 &#x1f393;容器适配器 &#x1f393;Stack栈 &#x1f6a9;Stack的介绍 &#x1f6a9;Stack的基本使用 &#x1f6a9;Stack底层实现 &#x1f393;queue队列 &#x1f6a9;queue的介绍 &#x1f6a9;queue的基本使用 &#x1f6a9;queue的底层实现 &#x1…

【C++】C++的IO流

一、C语言的输入与输出 C 语言中我们用到的最频繁的输入输出方式就是 scanf () 与 printf()。 scanf()&#xff1a;从标准输入设备&#xff08;键盘&#xff09;读取数据&#xff0c;并将值存放在变量中。printf()&#xff1a;将指定的文字/字符串输出到标准输出设备&#xff…

Java如何做到无感知刷新token含示例代码(值得珍藏)

1. 前言 在系统页面进行业务操作时&#xff0c;有时会突然遇到应用闪退&#xff0c;并被重定向至登录页面&#xff0c;要求重新登录。此问题的出现&#xff0c;通常与系统中用于存储用户ID和token信息的Redis缓存有关。具体来说&#xff0c;这可能是由于token过期所导致的身份…

容器部署的nextcloud配置onlyoffice时开启密钥

容器部署的nextcloud配置onlyoffice时开启密钥 配置 进入onlyoffice容器 docker exec -it 容器id bash编辑配置vi /etc/onlyoffice/documentserver/local.json enable设置为true&#xff0c;并配置secret 重启容器&#xff0c;并将配置的密钥填入nextcloud密钥页面 docker r…

复杂字幕特效SDK,重塑视频字幕新体验

字幕特效已经成为了提升视频品质、增强观众体验的重要手段。美摄科技作为行业领先的技术提供商&#xff0c;近期推出的复杂字幕特效SDK&#xff0c;更是引领了这一领域的创新潮流。 美摄科技复杂字幕特效SDK&#xff0c;不仅具备了电影级别的字幕功能&#xff0c;更实现了众多…

【全网最全】2024华数杯国际赛B题成品论文50页+1-4问高质量代码+完整数据集+建模过程+保姆级教学

基于数据分析下的光伏发电 摘 要&#xff08;完整版在文末&#xff09; 根据最新数据&#xff0c;中国的总发电量超过20万亿千瓦时&#xff0c;总体排名世界第一&#xff0c;而光伏发电是一种重要的可再生能源&#xff0c;可以将太阳能转化为电能可以减少对传统能源的依赖&…

VBA窗体跟随活动单元格【简易版】(2/2)

上一篇博客&#xff08;文章连接如下&#xff09;中使用工作表事件Worksheet_SelectionChange实现了窗体跟随活动单元格的动态效果。 VBA窗体跟随活动单元格【简易版】(1/2) 为了在用户滚动工作表窗体之后仍能够实现跟随效果&#xff0c;需要使用Application.Windows(1).Visibl…

归并排序详解

目录 ​&#x1f4a1;基本思想 &#x1f4a1;图文介绍 &#x1f4a1;动图演示 &#x1f4a1;过程解释 &#x1f4a1;代码实现 &#x1f4a1;递归实现 &#x1f4a1;非递归实现 &#x1f4a1;总结 &#x1f4a1;基本思想 归并排序&#xff08;MERGE-SORT&#xff09;是…

数据结构--串

本文为复习的草稿笔记&#xff0c;&#xff0c;&#xff0c;有点乱 1. 串的基本概念和基本操作 串是由零个或多个字符组成的有限序列 2. 串的存储结构 3.串的应用 模式匹配 BF算法&#xff08;简单匹配算法 穷举法 算法思路&#xff1a;从子串的每一个字符开始依次与主串…

深耕文档型数据库12载,SequoiaDB再开源

1月15日&#xff0c;巨杉数据库举行SequoiaDB新特性及开源项目发布活动。本次活动回顾了巨杉数据库深耕JSON文档型数据库12年的发展历程与技术演进&#xff0c;全面解读了SequoiaDB包括在高可用、安全、实时、易用性四个方向的技术特性&#xff0c;宣布了2024年面向技术社区的开…

无法打开浏览器开发者工具的可能解决方法

网页地址: https://jx.xyflv.cc/?url视频地址url 我在抖音里面抓了一个视频地址, 获取到响应的json数据, 找到里面的视频地址信息 这个网站很好用: https://www.jsont.run/ 可以使用js语法对json对象操作, 找到所有视频的url地址 打开网页: https://jx.xyflv.cc/?urlhttps:…

【Linux C | 文件操作】目录相关操作 | mkdir、rmdir、opendir、readdir、closedir、getcwd、chdir

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【LeetCode】栈精选9题

目录 1. 删除字符串中的所有相邻重复项&#xff08;简单&#xff09; 2. 逆波兰表达式&#xff08;中等&#xff09; 3. 基本计算器 II&#xff08;中等&#xff09; 4. 字符串解码&#xff08;中等&#xff09; 5. 验证栈序列&#xff08;中等&#xff09; 6. 小行星碰撞…

新能源汽车智慧充电桩方案:基于视频监控的可视化智能监管平台

一、方案概述 TSINGSEE青犀&触角云新能源汽车智慧充电桩方案围绕互联网、物联网、车联网、人工智能、视频技术、大数据、4G/5G等技术&#xff0c;结合云计算、移动支付等&#xff0c;实现充电停车一体化、充电桩与站点管理等功能&#xff0c;达到充电设备与站点的有效监控…

有效防范网络风险的关键措施

在数字化时代&#xff0c;企业面临着日益复杂和频繁的网络风险。提高员工的网络安全意识是防范网络威胁的关键一步。本文将探讨企业在提升网络安全意识方面可以采取的措施&#xff0c;以有效预防潜在的网络风险。 1. 开展网络安全培训&#xff1a;企业应定期组织网络安全培训&…