OJ刷题 第十五篇(递推较多,奥赛篇)

news2024/9/28 23:32:26

31005 - 昆虫繁殖(难度非常大,信息奥赛题)

时间限制 : 1 秒

内存限制 : 128 MB

科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强。每对成虫过x个月产y对卵,每对卵要过两个月长成成虫。假设每个成虫不死,第一个月只有一对成虫,且卵长成成虫后的第一个月不产卵(过x个月产卵),问过z个月以后,共有成虫多少对?0≤x≤20,1≤y≤20,X≤z≤50。

输入

x,y,z的数值。

输出

过z个月以后,共有成虫对数。

样例

输入

1 2 8

输出

37

 答案:

#include<iostream>
using namespace std;
int main()
{
    long long c[52] = { 0 }, r[52] = { 0 };//c[i]表示第i月成虫总数量,以对为单位,r[i]表示第i月新产生虫卵数量
    int x, y, z;
    cin >> x >> y >> z;
    for (int i = 1; i <= x; i++) {//前x个月没有产卵,因此这几个月成虫数量为1对,虫卵数量为0
        c[i] = 1;
        r[i] = 0;
    }
    //求Z月之后,成虫数量
    for (int i = x+1; i <= z + 1; i++) {
        r[i] = c[i - x] * y;
        c[i] = c[i - 1] + r[i - 2];  
    }
    cout << c[z + 1] << endl;
    return 0;
}

分析:本题难度非常大,首先是对题目的理解,整理如下:

1、每过x个月产一对卵,如果从第一个月开始算,假设我们只算第一对的产卵数量,假设x为1,则在第2月开始产卵,第三月也要产卵,以此类推;如果x为2,则从第三月开始产卵,第5月又要产卵,以此类推。因此每过x月产卵,即在当前月份+x得到的月份数即要开始产卵了。

2、题目求的是z月之后,比如z为8,即过了8个月之后,则隐含告诉我们就是求第9月的成虫数量。这是本题一个难点。

3、本题的核心是找出递推关系。设两个数组c[i]表示第i个月的成虫数量,r[i]表示第i个月的新产的虫卵数量,注意为什么强调是第i个月新产的虫卵数量。看下面推到:

先求c[i]:

我先告诉你结论,c[i]=c[i-1]+r[i-2],即第i月的成虫数量等于上一个月的成虫数量加上前两个月新产生的虫卵数量,就得到第i月的成虫数量。因为题目明确说了过了两个月虫卵才可以长成成虫。(这里题目可以加大难度,可以设一个变量,比如m月,那么原推倒就是c[i]=c[i-1]+r[i-m])

再求r[i]:

注意,第i月的成虫数量只跟某个月新产生的虫卵数量有关,先告诉结论:r[i]=c[i-x]*y,因为题目说的是每过x个月才开始产卵,因此我们求第i月的卵虫数量要在前面第i-x月的成虫数量中去找,比如x=1,y=2,假设当前是第5月,求第5月新产生的虫卵数量,我们要在第5-1=4,第4月中去找,因为它是每过x=1个月开始产卵,不知道你理解没有。仔细理解。比如x=2,y=2,当前仍然是第5月,求第5月新产生的虫卵,我们要在5-2=3,第三月的成虫数量中去找,r[5]=c[5-2]*2,即第3月的成虫数量乘以y(y这里为2),就得到第5月的新虫卵的数量。这里很难理解。也是本题最难的地方。因为虫卵是由成虫产生的,而我们现在求的是每月新产生的虫卵数量,新产生的虫卵只跟第i-x月的成虫数量有关,第i-x月的成虫产卵,过了x月,就得到第i月的新产生的虫卵数量。

是否通过:

 

31006 - 位数问题(难题,信息奥赛题,二刷、三刷、甚至四刷!)

时间限制 : 1 秒

内存限制 : 128 MB

在所有的N位数中,有多少个数中有偶数个数字3?由于结果可能很大,你只需要输出这个答案对12345取余的值。

输入

读入一个数N(N≤1000)。

输出

输出有多少个数中有偶数个数字3。

样例

输入

2

输出

73
#include<iostream>
using namespace std;
int main() {
    int a[1001], b[1001];//a[i]表示i位数中偶数3的个数,b[i]表示i位数中奇数3的个数
    int N;
    cin >> N;
    a[1] = 9;
    b[1] = 1;
    int x = 9;
    for (int i = 2; i <= N; i++) {
        if (i == N) {
            x = x - 1;
        }
        a[i] = (x * a[i - 1] + 1 * b[i - 1]) % 12345;
        b[i] = (x * b[i - 1] + 1 * a[i - 1]) % 12345;
    }
    cout << a[N] << endl;
    return 0;
}

分析:这个题难度非常大,首先对题目的意思可能就有很多人没理清。或者很多人一开始就是一个一个数的判断,这样对小规模的数可以,但是N大到一定数以后,就会运行超时。我当时在做的时候反正是没想到这是个递推。。看来是题目见得少。再开始分析之前有一点我们有必要知道:

偶数=偶数+偶数 或者 偶数=奇数+奇数

奇数=奇数+偶数 或者 奇数=偶数+奇数

下面开始分析:

当N=1时,即从0到9这10个数中,偶数个3的个数,很多人以为是0,因为只有一个3,没有偶数个,你别忘了,0它也是偶数,因此0~2 ,4~9都是0个3,即偶数个3有9个,奇数个3有1个。

当N为2时,即从10~99,我们最高位即十位不能为0,只能取1~9,。分两种情况:

当十位为偶数位3时时,即十位取1~2或者4~9,共8种情况,要想使得整个数3的个数为偶数,则个位上3的个数也必须为偶数个,而个位上可以取0,即,0~2,4~9,即9种情况。共有8*9=72种;

当十位为奇数个3时,即30~39,要想使得整个数3的个数为偶数个,那么个位数上的3的个数只能取奇数个,只有一种情况,即33。

故共有72+1=73种。

当N为3时,即从100~999,分析是一样的道理:

当百位为偶数个3,即1~2,4~9共8种情况,这时候只需让后面的十位和个位都取偶数位即可,且只能取偶数个3。注意,现在十位和个位都不是最高位,因此都能取到0,即0~2,4~9共9种,因此共有8*9*9=648种。

还有一种就是百位为偶数位,后面的十位和个位均为奇数位。即有

8*1*1=8种。

当百位为奇数位时,即只能取3,后面的十位和个位加起来得是奇数。若十位为偶数位,即~2,4~9,则个位只能取奇数个3,即个位只能取3,有1*9*1=9种;若十位为奇数位,即十位只能取3,则个位只能取偶数位,共1*1*9=9种。

共648+8+18=674种。

好了,到这里,我想你应该看出有那种递推的思想了。我们两个数组,a[i]、b[i]分别表示i为数的偶数个3的个数和奇数个3的个数。可以得到如下递推式子:

        a[i] = x * a[i - 1] + 1 * b[i - 1];(偶数等于偶数加偶数或者奇数加奇数)
        b[i] = x * b[i - 1] + 1 * a[i - 1];(奇数等于奇数加偶数或者偶数加奇数)

其中x=9。

 a[i] = x * a[i - 1] + 1 * b[i - 1];它的意思是在i为数中,求偶数个3的个数等于两种情况

1、第一位为偶数个3时,共x*a[i-1]

2、第一位为奇数个3时,共1*b[i-1]

b[i] = x * b[i - 1] + 1 * a[i - 1];它的意思是在i位数中,求奇数个3的个数等于两种情况

1、第一位为奇数个,共有1 *a[i-1]

2、第一位为偶数个,共有x*b[i-1]

共b[i] = x * b[i - 1] + 1 * a[i - 1]个

这个递推式是很难推出来的,而且这个版本比其他博主写的更难,因为把奇数的那一部分也求出来了。不仅能求偶数个,也能求奇数个。

但是这里要注意一点是,当求到最高位时,由于最高位不能取0,因此x得减1。 

是否通过:

31007 - 过河卒(经典问题!也是难题!)

时间限制 : 1 秒

内存限制 : 128 MB

棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上的某一点有一个对方的马(如C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点,如图中的C点和P1,……,P8,卒不能通过对方马的控制点。棋盘用坐标表示,A点(0,0)、B点(n, m) (n,m为不超过20的整数),同样马的位置坐标是需要给出的,C≠A且C≠B。现在要求你计算出卒从A点能够到达B点的路径的条数。

输入

给出n、m和C点的坐标。

输出

从A点能够到达B点的路径的条数。

样例

输入

8 6 0 4

输出

1617

 答案:

#include<iostream>
using namespace std;
long long dp[100][100];//因为第一次设置为int型,数据发生溢出,因此设置为long long类型
int main() {
	int n, m, x, y;
	cin >> n >> m >> x >> y;
	for (int i = 0; i <= n; i++) {
		for (int j = 0; j <= m; j++) {//先把每个点初始化为1,表示到该该点路径数为1
			dp[i][j] = 1;
		}
	}
	//对马的点和马的控制点进行赋值,使到这些点的路径数为0
	dp[x][y] = 0;
	if (x + 2 >= 0 && y + 1 >= 0)dp[x + 2][y + 1] = 0;
	if (x + 1 >= 0 && y + 2 >= 0)dp[x + 1][y + 2] = 0;
	if (x - 1 >= 0 && y + 2 >= 0)dp[x - 1][y + 2] = 0;
	if (x - 2 >= 0 && y + 1 >= 0)dp[x - 2][y + 1] = 0;
	if (x - 2 >= 0 && y - 1 >= 0)dp[x - 2][y - 1] = 0;
	if (x - 1 >= 0 && y - 2 >= 0)dp[x - 1][y - 2] = 0;
	if (x + 1 >= 0 && y - 2 >= 0)dp[x + 1][y - 2] = 0;
	if (x + 2 >= 0 && y - 1 >= 0)dp[x + 2][y - 1] = 0;

	//计算每个点的路径数
	for (int i = 0; i <= n; i++) {
		for (int j = 0; j <= m; j++) {
			if (i == 0 && j == 0) {//出发点不做任何处理
				continue;
			}
			if (dp[i][j] == 0) {//遇到马点和马的控制点也不不做任何处理
				continue;
			}
			//由于点的移动只能向右或者向下,对第一行和第一列要单独处理
			if (i == 0) {//第一行,若第一行有马点或马的控制点,则后面的点都不可达,设置为前一个点的值
				dp[i][j] = dp[i][j - 1];
			}
			if (j == 0) {//第一列,若第一列有马点或者马的控制点,则下面的点都不可达,设置为前一个点的值
				dp[i][j] = dp[i - 1][j];
			}
			if (i != 0 && j != 0) {//除了第一行、第一列以及马点和马的控制点,处理剩下的点
				dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
			}
		}
	}
	cout << dp[n][m] << endl;
	return 0;
}

分析:在做这个题之前,我是没什么头绪的,是查阅了资料进行整理才解决这个题。这个题是移动路线题的升级版。什么是移动路线,在力扣刷题库里,第64题。搞懂这个题,这个过河卒理解起来就简单多了。这个题难点就在处理马点和马的控制点。

首先我们要知道8个控制点怎么表示,其次得判断它们的合法性

其次就是对一一行和第一列的处理,这是许多这种类似题都要处理的地方。因为第一列和第一行比较特殊。所以要单独处理

是否通过:

31008 - 蜜蜂路线(难题!高进度加法!!)

时间限制 : 1 秒

内存限制 : 128 MB

一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房 M 开始爬到蜂房 N,M<N,有多少种爬行路线?(备注:题面有误,右上角应为 n-1)

输入

输入 M,N 的值。

输出

爬行有多少种路线。

样例

输入

1 14

输出 

377

提示

对于100%的数据,M,N <= 1000

答案:

#include<iostream>
using namespace std;
int n, m, a[5005] = { 1 }, b[5005] = { 1 }, c[5005] = { 1 }, len = 1;
void f() {
    int jw = 0;
    for (int i = 0; i < len; i++) {
        c[i] = a[i] + b[i] + jw;
        jw = c[i] / 10;
        c[i] %= 10;
    }
    if (jw != 0) {
        c[len] = jw;
        len++;
    }
    for (int i = 0; i < len; i++) {
        a[i] = b[i];
        b[i] = c[i];
    }
}
int main() {
    cin >> m >> n;
    for (int i = 3; i <= n - m + 1; i++) {
        f();
    }
    for (int i = len - 1; i >= 0; i--) {
        cout << c[i];
    }
    return 0;
}

分析:其实这道题逻辑很简单,就是一个题目变换的斐波那契数列,推倒公式为

f(n)=f(n-1)+f(n-2),但是我们知道,之前做的斐波那契数列在第46项就已经达到18亿,第47项溢出,即使改为long long类型,也只是到第103项,题目给出N最大可以到1000项,显然long long类型也是不够的。那么怎么办呢?用double吗??你要知道,斐波那契数列是指数级增长的,平时的加法已经在这里不适用了。因为后面的数都太大了,所以这个题要用到高精度加法,也就是我们熟悉的大数加法运算。所以很多人在这个题用long long只能通过前两个测试点,第三个测试点不能通过。

大数加法怎么做呢?很简单就是模拟普通加法运算,我们需要借助一个变量作为进位,设进位变量为jw,初始值为0。

每当一个数进行加以后,我们取的是后面那一位的值,比如8+6=14,这一位取4,1向前面进位。

设a[i]和b[i]分别表示两个大数,c[i]表示两数求的和,两数相加时有如下:

c[i]=a[i]+b[i]+jw;

jw=c[i]/10;

c[i]=c[i]%10;

这是大数加法运算得核心步骤。然后再用一个全局变量记录 c[i]即和的长度,然后把

a[i]=b[i];

b[i]=c[i];

这个是实现递推。到这里说一下我的感受,OJ系统到这里都是一些比较难的题目了,而且难度明显比之前难了不少。但是之前那些题可能见得比较多,所以上手起来并不是很难,而后面这些题遇到的不多,尤其像这个大数加法,遇到的是真的不多,因此后面二刷甚至三刷的时候建议多刷这种题,这也是比赛喜欢出的题。

是否通过:

31011 - 上台阶

时间限制 : 1 秒

内存限制 : 128 MB

楼梯有n(71>n>0)阶台阶,上楼时可以一步上1阶,也可以一步上2阶,也可以一步上3阶,编程计算共有多少种不同的走法。

输入

输入的每一行包括一组测试数据,即为台阶数n。最后一行为0,表示测试结束。

输出

每一行输出对应一行输入的结果,即为走法的数目。

样例

输入

1
2
3
4
0

输出

1
2
4
7

答案:

#include<iostream>
using namespace std;
int main() {
	int n;
	while (true) {
		cin >> n;
		if (n) {
			long long sum = 0,f1=1,f2=2,f3=4;
			if (n == 1) {
				sum = f1;
			}
			else if (n == 2) {
				sum = f2;
			}
			else if (n == 3) {
				sum = f3;
			}
			else {
				for (int i = 4; i <= n; i++) {
					sum = f1 + f2 + f3;
					f1 = f2; f2 = f3;
					f3 = sum;
				}
			}
			cout << sum << endl;
		}
		else {
			break;
		}
	}
	return 0;
}

分析:这道题其实之前做了,骨牌铺法那道题就是三层推导,或者说是三个递推关系f(n)=f(n-1)+f(n-2)+f(n-3),这里写在这里就是回顾一下,另外要知道f3=4为什么??

假设第一步:有三种走法,第一个阶梯,第二个阶梯,第三个阶梯,走到第二和第三其实这只能是一种走法,走到第三阶梯后面没阶梯了,因此这是一种,其次走到第二阶梯,剩下一个阶梯也只能有一种走法。

如果第一步走到第一个阶梯,那么剩下的两种阶梯就有两种走法,要么一步一步走到第三阶梯,要么一步走到第三阶梯,因此共4种走法。

是否通过:

 

 

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

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

相关文章

从零开始 Spring Boot 27:IoC

从零开始 Spring Boot 27&#xff1a;IoC 自从开始学习和从事Spring Boot开发以来&#xff0c;一个一直让我很迷惑的问题是IoC和Bean到底是什么东西。这个问题一直到我翻阅完Spring开发文档Core Technologies (spring.io)后才真正得到解惑。 虽然中文互联网上关于IoC的文章很多…

基于AT89C51单片机的电子琴设计与仿真

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/87765092?spm1001.2014.3001.5503 源码获取 运用单片机&#xff0c;将音乐的大部分音符与相应按键相匹配&#xff0c;让音乐爱好者利用单片机也可以进行演奏。 基…

SAP EWM /SCWM/CHM_LOG - 显示及分析检查日志

很多公司上了EWM系统后会在运行一段时间之后出现一些系统数据异常情况&#xff0c;问题大致分为以下一些情况&#xff1a; 序号异常情况1 库存调整过账后可用数量的数据不正确2 错误地传输原产国 (2)3 HU 在可用库存中&#xff0c;即使不允许 HU4 非 AQUA 级别创建仓库任务后可…

TCP通讯(三次握手、四次挥手;滑动窗口;TCP状态转换;端口复用;TCP心跳检测机制)

前言&#xff1a;建议看着图片&#xff0c;根据文字描述走一遍TCP通讯过程&#xff0c;加深理解。 目录 TCP通信时序&#xff1a; 1&#xff09;建立连接&#xff08;三次握手&#xff09;的过程&#xff1a; 2&#xff09;数据传输的过程&#xff1a; 3&#xff09;关闭连…

智能优化算法:斑马优化算法-附代码

智能优化算法&#xff1a;斑马优化算法 文章目录 智能优化算法&#xff1a;斑马优化算法1.斑马优化算法1.1 初始化1.2 阶段一&#xff1a;觅食行为1.3 阶段二&#xff1a;针对捕食者的防御策略 2.实验结果3.参考文献4.Matlab 摘要&#xff1a;斑马优化算法&#xff08;Zebra Op…

协同设计有什么优势?都有哪些协同设计软件

设计师创作既有视觉吸引力又实用的作品需要很多时间。对于某些项目&#xff0c;第一次可能会顺利验收&#xff0c;但事实上&#xff0c;设计和修改总是伴随着。 如何有效地修改和促进项目的实施&#xff1f;答案很简单&#xff1a;协作设计。本文将带您深入学习协作设计的相关…

Spring01-Spring简介、IOC简介及入门、IOC详解、bean讲解、依赖注入、配置文件模块化、实现CRUD

Spring简介 一、Spring 是什么 Spring 是一个分层的 Java SE/EE full-stack (一站式) 轻量级开源框架 以 IOC &#xff08;Inverse Of Control:反转控制) 和 AOP &#xff08;Aspect Oriented Programming:面向切面编程) 为核心。 在 Java三层架构中 分别提供了响应技术 分…

docker php安装redis扩展

有这么一个情况&#xff0c;我在docker中&#xff0c;安装了镜像&#xff0c;也启动了容器&#xff0c;容器有&#xff1a;nginx、mysql、redis、php 是一个基本的开发环境 容器启动成功&#xff0c;我们先连接一下&#xff0c;看看是否正常。 先保证这些都ok&#xff0c;我们…

【Spring框架一】——Spring框架简介

系列文章目录 Spring框架简介 系列文章目录前言一、什么是Spring框架&#xff1f;二、Spring框架的优势1.简化开发流程&#xff1a;Spring提供了许多现成的功能&#xff0c;可以使得开发人员在构建应用程序时减少编写重复代码的工作。2.提高可维护性&#xff1a;Spring框架采用…

chatgpt搜索脚本

安装地址 https://greasyfork.org/zh-CN/scripts/459997 注意事项 &#xff01;&#xff01;注意&#xff1a;如果你在360相关浏览器上使用插件。360搜索将不会生效&#xff0c;因为已被浏览器禁用在so.com网址上使用。 &#xff01;&#xff01;尽量选择tampermonkey脚本管…

面试华为测试岗,收到offer后我却毫不犹豫拒绝了....

我大学学的是计算机专业&#xff0c;毕业的时候&#xff0c;对于找工作比较迷茫&#xff0c;也不知道当时怎么想的&#xff0c;一头就扎进了一家外包公司&#xff0c;一干就是2年。我想说的是&#xff0c;但凡有点机会&#xff0c;千万别去外包&#xff01; 在深思熟虑过后&am…

Android性能优化专家需求量大,人才缺口呼之欲出

前言 Android性能优化是Android应用开发中一个非常重要的环节。一款高性能、流畅的应用可以提高用户体验和满意度&#xff0c;提升应用的用户留存率和活跃度。而在今天&#xff0c;移动设备日趋普及&#xff0c;市场竞争日益激烈&#xff0c;优秀的性能已经成为了Android应用不…

Android安卓手机APP应用自有keystore签名证书怎么生成?

Android安卓keystore签名证书怎么生成&#xff1f; 1、安装JRE环境 Oracle官方下载jre安装包&#xff1a;https://www.caochai.com/article-4206.html &#xff0c;并记住安装的目录&#xff1b; 2、打开电脑上的cmd命令提示符工具&#xff0c;先进入jre安装目录&#xff1b…

宿主机(Windos)上文件上传至Ubuntu (linux)

因为我想在ubuntu20.04 上安装Sublime Text ,然而我不想在ubuntu 上下载安装因为太简单了。 我想在windos 上下载好linux 版本&#xff0c;然后发送到ubuntu上&#xff08;和ubuntu上下载安装多了一个上传的过程&#xff09;&#xff0c;我决定挑战一下 第一步进入VM 后打开你…

【Linux学习】多线程——互斥 | 线程安全

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 互斥 | 线程安全 &#x1f969;线程不安全&#x1f35a;线程不安全的原因 &#x1f969;线程互斥…

网络编程五--自定义应用层协议

写在前面 前面回声服务器/客户端介绍了如何通过对收发IO的控制实现回声服务器/客户端。 在服务器端应用层的处理&#xff08;协议&#xff09;可以看作是“回声操作”&#xff0c;即回发客户端发来的消息。而在客户端应用层的处理&#xff08;协议&#xff09;则只是简单显示…

Mysql获取指定时间范围数据

MySQL获取某个时间范围内的数据 TO_DAYS(date)函数。 to_days()&#xff1a;返回从0000年至当前日期的总天数。 目录 1、今天(TO_DAYS()) 2、今天昨天(TO_DAYS()) 3.近7天(DATE_SUB()) 5.本月(DATE_FORMAT()) 6.上一月(PERIOD_DIFF()) 7.本季度 8.上季度 9.本年 ​1…

MyBatis介绍、创建与使用

文章目录 一、MyBatis是什么二、学习 MyBatis 的意义三、配置 MyBatis 开发环境&#xff08;一&#xff09;配置 MyBatis 的相关依赖&#xff08;二&#xff09;配置数据库连接字符串和 MyBatis&#xff08;保存的 XML 目录&#xff09;1. 创建并编辑配置文件2. 配置 MyBatis 的…

[GFCTF 2021]ez_calc day3

目录 此时我脑袋产生了几个问题&#xff1a; 但是尝试了几个弱密码发现不对&#xff0c;找一下有没有代码泄露的点。 咦发现ctrlu查看的源码和f12显示的竟然不一样我丢&#xff0c;涨知识了。 js大小写有漏洞之前遇见过 <!--if(req.body.username.toLowerCase() ! admin…

Maven与spring学习

目录 该如何学习Maven&#xff0c;是先该学习spring还是先学习Maven 能讲一下该如何学习Maven吗&#xff1f; 火狐浏览器有能让网页翻译成为中文的插件吗 秋田和柴犬是同一个狗吗 该如何学习Maven&#xff0c;是先该学习spring还是先学习Maven 学习Maven可以与学习Spring同…