【递归专题】【蓝桥杯备考训练】:有序分数、正则问题、带分数、约数之和、分形之城【已更新完成】

目录

1、有序分数(usaco training 2.1)

2、正则问题(第八届蓝桥杯省赛C++ A组 & Java A组)

3、带分数(第四届蓝桥杯省赛Java A组/B组 & C++ B组/C组)

4、约数之和(《算法竞赛进阶指南》)

5、分形之城(《算法竞赛进阶指南》)


1、有序分数(usaco training 2.1)

给定一个整数 N,请你求出所有分母小于或等于 N,大小在 [0,1]范围内的最简分数,并按从小到大顺序依次输出。

例如,当 N=5 时,所有满足条件的分数按顺序依次为:

0/1,1/5,1/4,1/3,2/5,1/2,3/5,2/3,3/4,4/5,1/1

输入格式

共一行,包含一个整数 N。

输出格式

按照从小到大的顺序,输出所有满足条件的分数。

每个分数占一行,格式为 a/b,其中 a 为分子, b为分母。

数据范围

1≤N≤160

输入样例:
5
输出样例:
0/1
1/5
1/4
1/3
2/5
1/2
3/5
2/3
3/4
4/5
1/1
思路:

用一个pair对来维护最小值对应的分子分母,将所有情况枚举,为了避免重复我们要用一个set来确保没有重复的数值

这里要注意进入递归函数要直接进入最里面的一层开始往上递归,这样就可以做到所有分数的都是最简分数式

代码:

#include<bits/stdc++.h>using namespace std;int n;typedef pair<int,int> PII;typedef pair<double,PII> PDP;const int N=1e5;vector<PDP>res;unordered_set<double>cnt;void work(int n)
{if(n==0)return ;work(n-1);for(int i=n-1;i>0;i--){double number=(double)i/n;if(cnt.find(number)!=cnt.end())continue;cnt.insert(number);PII t={i,n};res.push_back({number,t});}}bool cmp(PDP a,PDP b)
{return a.first<b.first;
}int main()
{cin>>n;res.push_back({0,{0,1}});res.push_back({1,{1,1}});work(n);sort(res.begin(),res.end(),cmp);for(auto t:res){cout<<t.second.first<<"/"<<t.second.second<<endl;}return 0;
} 

2、正则问题(第八届蓝桥杯省赛C++ A组 & Java A组)

考虑一种简单的正则表达式:

只由 x ( ) | 组成的正则表达式。

小明想求出这个正则表达式能接受的最长字符串的长度。

例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是: xxxxxx,长度是6。

输入格式

一个由x()|组成的正则表达式。

输出格式

输出所给正则表达式能接受的最长字符串的长度。

数据范围

输入长度不超过100,保证合法。

输入样例:
((xx|xxx)x|(x|xx))xx 
输出样例:
6
思路:

递归+回溯

代码:
#include<bits/stdc++.h>using namespace std;int k=0;string s; //((xx|xxx)x|(x|xx))xx 
//6
int dfs()
{int res=0;while(k<s.size()){if(s[k]=='('){k++;res+=dfs();k++;}else if(s[k]==')'){break;}else if(s[k]=='|'){k++;res=max(res,dfs());}else{k++;res++;}}return res;
}int main()
{cin>>s;int res=dfs();cout<<res;return 0;
}

3、带分数(第四届蓝桥杯省赛Java A组/B组 & C++ B组/C组)

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

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

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

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

输入格式

一个正整数。

输出格式

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

数据范围

1≤N<1e6

输入样例1:
100
输出样例1:
11
输入样例2:
105
输出样例2:
6
思路:

由于c++的/并不准确,我们把除法转化为乘法,再进行枚举(n=a+b/c转化为nc=ac+b)

从而我们枚举出a和c就可以算出b,b=nc-ac;

用had_use记录用过的数,ever用来在不影响并行递归的情况下把当前情况递归下去(不破坏原来的记录)

代码:
#include<bits/stdc++.h>using namespace std;const int N=600;//typedef long long LL;int ever[N],had_use[N];
//数组放在最上面,acwing平台由于放在了ans下面导致输出结果错误 int ans=0;int  n;//n=a+b/c
//nc=ac+b
//b=nc-ac 只要推出来的b满足条件,a和c都满足条件则答案+1 
bool check(int a,int c)
{int b=n*c-a*c;if(!a || !c || !b)return false;memcpy(ever,had_use,sizeof had_use);//基于现有的情况下,不破坏原来的数组//那就拷贝一份,既能在原来之上操作,又能不破坏原来的记录 while(b)//取出每一位,用来更新用过的数字 {int t=b%10;b/=10;if(!t || ever[t])return false;ever[t]=1;}for(int i=1;i<=9;i++)if(!ever[i])return false;return true;
}void dfs_c(int x,int a,int c)
{if(x>=10)return ;if(check(a,c))ans++;for(int i=1;i<=9;i++){if(!had_use[i]){had_use[i]=1;dfs_c(x+1,a,c*10+i);had_use[i]=0;//回溯,避免下次的递归中出现错误 }}
}void dfs_a(int x,int a)
{if(a>=n)return;if(a)dfs_c(x,a,0);//如果a满足条件,那么枚举c然后判断是否是成立的//0是c的大小 for(int i=1;i<=9;i++)//枚举一下当前能用哪些数字{if(!had_use[i]){had_use[i]=1;dfs_a(x+1,a*10+i);had_use[i]=0;//恢复现场,回溯一下 }	} 
}int main()
{	//cout<<714*97;cin>>n;dfs_a(0,0);//第一个表示当前用了多少个数字,第二个参数表示当前的a是多少 cout<<ans;return 0;
}

4、约数之和(《算法竞赛进阶指南》)

假设现在有两个自然数 A 和 B,S 是A的B次方的所有约数之和。

请你求出 S mod9901 的值是多少。

输入格式

在一行中输入用空格隔开的两个整数 A 和 B。

输出格式

输出一个整数,代表 Smod9901 的值。

数据范围

0≤A,B≤5×1e7

输入样例:
2 3
输出样例:
15

注意: A 和 B不会同时为 0。

思路:

分解质因数,把每个质因数的从第0项到最高次数的和乘起来就是约数之和

由于是求A的B次方的约数之和,我们可以先把A分解质因数,次方B可以后来再给到质因数的次方上

代码:
#include<bits/stdc++.h>using namespace std;const int MOD=9901;typedef long long LL;LL a,b;
LL res=0;unordered_map<int,int>primes;LL quickmi(LL a,LL b)
{LL res=1;while(b){if(b&1)res=res*a%MOD;a=a*a%MOD;b=b>>1;}return res%MOD;
}void divide(LL x)
{for(int i=2;i<=x/i;i++){if(x%i==0){while(x%i==0){primes[i]++;x/=i;}}}if(x>1)primes[x]++;
}//求p0+....pk-1 
LL sum(LL p,LL k)
{if(k==1)return 1;if(k%2==0)return (LL)(quickmi(p,k/2)+1)*sum(p,k/2)%MOD;return (LL)(quickmi(p,k-1)+sum(p,k-1))%MOD;
}int main()
{cin>>a>>b;divide(a);LL res=1;for(auto prime :primes){int p=prime.first;int k=prime.second*b;//p的次数 res=(LL)res*sum(p,k+1)%MOD;//求约数之和 }if(!a)res=0;cout<<res<<endl; return 0;
}

5、分形之城(《算法竞赛进阶指南》)

城市的规划在城市建设中是个大问题。

不幸的是,很多城市在开始建设的时候并没有很好的规划,城市规模扩大之后规划不合理的问题就开始显现。

而这座名为 Fractal 的城市设想了这样的一个规划方案,如下图所示:

city.png

当城区规模扩大之后,Fractal 的解决方案是把和原来城区结构一样的区域按照图中的方式建设在城市周围,提升城市的等级。

对于任意等级的城市,我们把正方形街区从左上角开始按照道路标号。

虽然这个方案很烂,Fractal 规划部门的人员还是想知道,如果城市发展到了等级 N,编号为 A 和 B 的两个街区的直线距离是多少。

街区的距离指的是街区的中心点之间的距离,每个街区都是边长为 10 米的正方形。

输入格式

第一行输入正整数 n,表示测试数据的数目。

以下 n 行,输入 n 组测试数据,每组一行。

每组数据包括三个整数 N,A,B表示城市等级以及两个街区的编号,整数之间用空格隔开。

输出格式

一共输出 n 行数据,每行对应一组测试数据的输出结果,结果四舍五入到整数。

数据范围

1≤N≤31
1≤A,B≤2**2N
1≤n≤1000

输入样例:
3 
1 1 2 
2 16 1 
3 4 33 
输出样例:
10 
30 
50 
思路:

我们要知道第n等级城市的信息就要知道n-1等级的(n-1等级的城市可以通过旋转变换得出n等级城市的坐标信息),递归下去,最后算出街区中心坐标然后进行勾股定理即可,注意要乘上单位长度(本代码为5)

代码:
#include<bits/stdc++.h>typedef long long LL;using namespace std;typedef pair<LL,LL> PLL;#define x first#define y secondPLL calc(LL n,LL m)
{//n代表城市等级 //m代表坐标,从0开始计数 if(n==0)return {0,0};LL len = 1ll <<(n-1);//本等级内象限的边长/2 LL cnt=1ll<<(2*n-2);//上一等级的容量PLL pos = calc(n - 1, m % cnt);  // 上一等级的坐标信息 LL x=pos.x,y=pos.y;int z=m/cnt;//处于哪个象限 if (z == 0)return { - y - len, - x + len };// 右上象限更换原点(x+len,y+len)else if (z == 1)return { x + len, y + len };// 右下象限更换原点(x+len,y-len)else if (z == 2)return { x + len, y - len };// 左下象限逆转90°(-y,x)沿y对称(y,x)更换原点(y-len,x-len)return { y - len, x - len };
}int main()
{int N;cin >> N;while (N --){LL n, m1, m2;cin >> n >> m1 >> m2;PLL pos1 = calc(n, m1 - 1);PLL pos2 = calc(n, m2 - 1);double x = (double) (pos1.first - pos2.first);double y = (double) (pos1.second - pos2.second);//单位长度要乘五printf("%.0lf\n", sqrt(x * x + y * y) * 5);}return 0;
}

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

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

相关文章

图形学 总结 - 老是忘

渲染流水线&#xff1a; 1、首先相机摆放到场景一个位置和角度&#xff0c;场景的各个物体也已经被摆放好 2、拿到场景物体的顶点信息&#xff0c;根据顶点信息构成图元 3、经过透视投影&#xff0c;将图元转化为2*2的正方形&#xff0c;再把2*2的正方形扩展到屏幕大小 4、…

修复 error Delete `␍` prettier/prettier 错误

修复 error Delete ␍ prettier/prettier 错误 问题背景报错信息报错原因解决办法修改CRLF----针对单个文件yarn run lint --fix 一键修复&#xff08;官方提供&#xff09; 问题背景 今天在使用 openapi 自动生成前端接口代码的时候&#xff0c;爆了一个类似 eslint 规范的错…

机器人路径规划:基于流场寻路算法(Flow Field Pathfinding)的机器人路径规划(提供Python代码)

流场寻路算法(Flow Field Pathfinding)是一种基于流体动力学理论的路径规划算法&#xff0c;它模拟了流体在空间中的流动&#xff0c;并利用流体的运动特性来指导路径的选择。下面是流场寻路算法的基本介绍及算法描述&#xff1a; 1. 基本介绍 流场寻路算法通过将环境划分为网…

算法导论第十二章练习参考答案(22) - 12.1-12.4

Exercise 12.1-1 任何时候&#xff0c;如果一个节点有一个子节点&#xff0c;就把它当作右子节点&#xff0c;左子节点为NIL。 Exercise 12.1-2 二叉搜索树的属性保证了左子树的所有节点都更小&#xff0c;右子树的所有节点都更大。最小堆属性只保证一般的子节点大于父节点的关…

你在测试金字塔的哪一层(上)

​在准备将软件上线到生产环境之前需要进行测试。随着软件测试方式日趋成熟&#xff0c;软件开发团队的测试也在取代大量手动测试&#xff0c;逐渐实现自动化测试。 通过自动化测试&#xff0c;开发团队可以在短短几分钟内就了解到软件是否存在问题&#xff0c;而不需要等待几天…

航空公司遭遇Play恶意家族攻击,亚信安全发布《勒索家族和勒索事件监控报告》

本周态势快速感知 本周全球共监测到勒索事件95起&#xff0c;与上周相比数量持平。 本周Play是影响最严重的勒索家族&#xff0c;Blacksuit和Ransomhub恶意家族紧随其后&#xff0c;从整体上看lockbit3.0依旧是影响最严重的勒索家族&#xff0c;需要注意防范。 本周大陆航空技…

【鸿蒙HarmonyOS开发笔记】常用组件介绍篇 —— 弹窗组件

简介 弹窗是移动应用中常见的一种用户界面元素&#xff0c;常用于显示一些重要的信息、提示用户进行操作或收集用户输入。ArkTS提供了多种内置的弹窗供开发者使用&#xff0c;除此之外还支持自定义弹窗&#xff0c;来满足各种不同的需求。 下面是所有涉及到的弹窗组件官方文档…

CSS 浮动

浮动 在标准流当中&#xff0c;元素或者标签在页面上摆放的时候会出现不如意的地方。要想解决这些问题可以采用脱离标准流的方式来进行解决这些问题&#xff0c;脱离标准流也称为脱离文档流。 脱离标准流的解决方式有三种&#xff0c;一种是浮动&#xff0c;另外一种是固定定位…

如何读懂磁滞回曲线(磁化曲线、退磁曲线、内禀曲线)

硬磁性材料&#xff0c;如钕铁硼磁钢&#xff0c;有两个显著特征&#xff0c;一是在外磁场作用下能被强烈磁化&#xff0c;另一个是磁滞&#xff0c;即撤走外磁场后硬磁材料仍保留磁化状态&#xff0c;下图为硬磁材料的磁感应强度B与磁化场强度H之间的关系曲线。 当磁场按Hs→H…

算法——贪心

「贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优」 贪心无套路 1. 分发饼干 贪心策略&#xff1a; &#xff08;1&#xff09;局部最优就是大饼干喂给胃口大的&#xff0c;充分利用饼干尺寸喂饱一个&#xff0c;全局最优就是喂饱尽可能多的小孩 &#xff08…

Linux chapter1 常用命令 cp

note 1 : netstat、curl、ip、nmap、dig 这些都是常用的网络诊断工具&#xff0c;它们的全称如下&#xff1a; netstat&#xff1a;Network Statistics&#xff0c;网络统计&#xff0c;用于显示网络连接&#xff0c;路由表&#xff0c;网络接口统计等网络信息。curl&#xf…

Kali Linux 更换优质国内源

文章目录 环境说明1 Kali Linux 源简介2 Kali Linux 更换国内源 环境说明 操作系统&#xff1a;kali-linux-2024.1-installer-amd64 1 Kali Linux 源简介 所谓的 Kali Linux 源&#xff0c;你可以将它理解为软件仓库&#xff0c;系统通过它安装和更新软件&#xff1b;源的服务…

nodeJs 学习

常用快捷键 二、fs模块 回调函数为空&#xff0c;则表示写入成功&#xff01; 练习 const fs require(fs); fs.readFile(../files/成绩.txt, utf-8, (err, dataStr) > {if (err) {console.log(读取失败);return err;}console.log(读取成功);const arr dataStr.split( )co…

RPC 和 序列化

RPC 1 RPC调用流程 1.1 clerk客户端调用远程服务 Clerk::PutAppend() raftServerRpcUtil::PutAppend() raftServerRpcUtil是client与kvserver通信的入口&#xff0c; 包含kvserver功能的一对一映射&#xff1a;Get/PutAppend&#xff0c;通过stub对象——raftKVRpcProctoc:…

web前端之实现复选功能、repeat

MENU 1、原生实现1.1、html部分1.2、JavaScript部分1.3、css部分1.4、效果图 2、uniApp实现2.1、html部分2.2、JavaScript部分2.3、css部分2.4、效果图 1、原生实现 1.1、html部分 暂时为null&#xff0c;后续会补充。1.2、JavaScript部分 暂时为null&#xff0c;后续会补充…

算法第二十九天-森林中的兔子

森林中的兔子 题目要求 解题思路 重点&#xff1a;某个兔子回答x的时候&#xff0c;那么数组中最多循序x1个同花色的兔子同时回答x 我们可以通过举例子得出一下的规律&#xff1a; 我们统计数组中所有回答x的兔子的数量n&#xff1a; 若n%(x1)0&#xff0c;说明我们此时只需…

Vector[C++]

文章目录 C中的std::vector简介std::vector的特点std::vector的重要接口用法介绍1. 初始化vector 2. 添加元素push_backemplace_back 3. 访问元素operator[]back 4. 修改元素operator 5. 遍历三种&#xff0c;下标&#xff0c;迭代器&#xff0c;范围for 6. 容量和大小sizeempt…

Induction or tail-recursion

选择排序 遍历整个待排序的数组&#xff0c;从第一个元素开始。在未排序的部分中&#xff0c;找到最小&#xff08;或最大&#xff09;的元素&#xff0c;并将其与第一个元素交换位置。接着从第二个元素开始&#xff0c;重复步骤2&#xff0c;直到所有元素都被排序 迭代版 递…

Qt实现简单的五子棋程序

Qt五子棋小程序 Qt五子棋演示及源码链接登陆界面单机模式联机模式联网模式参考 Qt五子棋 参考大佬中国象棋程序&#xff0c;使用Qt实现了一个简单的五子棋小程序&#xff0c;包含了单机、联机以及联网三种模式&#xff1b;单机模式下实现了简易的AI&#xff1b;联机模式为PtoP…

OPTIONS请求(跨域预检查)

目录 一、什么是OPTIONS请求&#xff1f;二、简单请求、复杂请求三、特定的请求头、响应头 一、什么是OPTIONS请求&#xff1f; OPTIONS 请求方式是 HTTP 协议中的一种&#xff0c;主要用于 从响应头中获取服务器支持的HTTP请求方式。 OPTIONS 请求方式是 浏览级行为&#xf…