C++伯罗奔尼撒箭阵 全国信息素养大赛复赛决赛 C++小学/初中组 算法创意实践挑战赛 内部集训模拟题详细解析

C++伯罗奔尼撒箭阵

全国信息素养大赛 C++复赛/决赛模拟练习题

博主推荐

1、C++专栏 

  1. 电子学会C++一级历年真题解析
  2. 电子学会C++二级历年真题解析
  3. 蓝桥杯C++选拔赛真题解析
  4. 信息素养大赛C++算法编程挑战赛

 2、Python专栏

  1. 蓝桥杯python选拔赛真题详解
  2. 蓝桥杯python省赛真题详解
  3. 蓝桥杯python国赛真题详解
  4. 信息素养大赛python编程挑战赛
  5. python等级一级真题解析【电子学会】
  6. python等级二级真题解析【电子学会】
  7. python等级三级真题解析【电子学会】

一、题目要求

1、编程实现

        在伯罗奔尼撒战争中,为了应对敌方的箭阵,指挥官正在研究一种新的列队方式,为了方便士兵理解, 抽象如下:给出正整数 n ,要求按如下方式构造数列:
  1.  只有一个数字 n 的数列是一个合法的数列。
  2. 在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列。
        请你帮助指挥官求出,一共有多少个合法的数列。两个合法数列 a , b 不同当且仅当两数列长度不同或 存在一个正整数 i a ,使得 a i b i

2、输入输出

输入描述:输入只有一行一个整数,表示 n

输出描述:输出一行一个整数,表示合法的数列个数。

输入样例:

6

输出样例:

6
样例 解释: 满足条件的数列为:6、6,1、6,2、6,3、6,2,1、6,3,1
数据规模: 数据保证, 对于全部的测试点,保证 1≤ n 10^ 3  

二、算法分析

  1. 从给定题目的初步分析可以看出,本题是一个数论问题,求符合要求的数列
  2. 可以使用DFS,也可以使用动态规划DP,还可以使用前缀和等多种算法实现
  3. 这里采用DP方式和前缀和方式进行实现,这两种算法的效率要比DFS高一些
  4. DP[i]指的是数字为i时合法的数列个数
  5. 状态转移方程:每个数字i本身就是一个合法数列,所以dp[i]=1;同时满足j从数字从1到i的一半的数字的合法数列累加,所得到的的状态转移方程为:dp[i]+=dp[j]
  6. 前缀和的思路和上面状态转移方程的思路类似,只是少一层循环,多一个数组;即dp[i]=1+a[i/2],a[i] = a[i-1] + dp[i]

三、程序编写

//方法一:态规划DP实现 
#include<iostream>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int dp[n+1] = {0};
	dp[1] = 1;//初始 
	for(int i=2;i<=n;i++) 
	{
		dp[i] = 1;//每个数字都是1 
		for(int j=1;j<=i/2;j++)
			dp[i] += dp[j];
	}
	cout << dp[n];
	return 0;
} 

//方法一:前缀和+dp实现 
#include<iostream>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int dp[n+1] = {0};
	int s[n+1] = {0}; 
	dp[1] = 1;//初始 
	s[1] = 1; //存放前缀和 
	for(int i=2;i<=n;i++) 
	{
		dp[i] = 1 + s[i/2];
		s[i] =  s[i-1] + dp[i]; 
	}
	cout << dp[n];
	return 0;
} 

 本文作者:小兔子编程 作者首页:https://blog.csdn.net/frank2102

四、运行结果

6
6

8
10

五、考点分析

难度级别:一般,这题相对而言有一定难度,具体主要考察如下:

  1. 分析题目 找到解题思路
  2. 充分掌握数组的定义和使用
  3. 学会输入流对象cin的使用,从键盘读入相应的数据
  4. 学会for循环的使用,在确定循环次数的时候推荐使用学会
  5. 学会while循环的使用,在不确定循环次数的时候推荐使用
  6. 掌握动态规划算法DP的解题思路和状态转移方程
  7. 学会前缀和算法的原理和解题思路
  8. 掌握输出流对象cout的使用,与流插入运算符 << 结合使用将对象输出到终端显示
  9. 学会分析题目,算法分析,将复杂问题模块化,简单化,从中找到相应的解题思路
  10. 充分掌握变量定义和使用、分支语句、循环语句和DP算法知识的使用及输入输出的用法

PS:方式方法有多种,小朋友们只要能够达到题目要求即可!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小兔子编程

您的鼓励是我创作优质案例的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值