重刷PTA递推实验

本文通过C语言实现一系列编程算法,包括模拟马在棋盘上的行走路径计数、兔子繁殖数量计算、母牛数量随年份增长的规律等数学问题。每个问题都给出了详细的代码实现,旨在帮助读者理解并掌握动态规划和递推序列在编程中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 马拦过河卒 (20 分)

#include<stdio.h>
int main()
{
    int a[9]={0,-1,-1,1,1,2,2,-2,-2};
    int b[9]={0,2,-2,2,-2,1,-1,1,-1};//表示马可能存在的九个点位;
    int map[16][16]={0};//相当于做一个“棋盘”;
    long long can[16][16]={0};//表示可以通行的点位;
    int n,m,x,y,i,j;
    scanf("%d %d %d %d",&n,&m,&x,&y);
    for(i=0;i<16;i++)
        for(j=0;j<16;j++)
            map[i][j]=1;//首先让整个“棋盘”均可通行,定义点位值为‘1’是可通行的点;
    for(i=0;i<9;i++)
    {
        if(a[i]+x<=15&&a[i]+x>=0&&b[i]+y>=0&&b[i]+y<=15)//马所在点位不能出棋盘这个边界;
            map[a[i]+x][b[i]+y]=0;//让马所在点位的点变成不能通行的点,也就是点位值为‘0’;
    }
    for(i=0;i<16;i++)
    {
        if(map[i][0]==1)//行操作,如果“棋盘”上的点位值为1,表示其可通过;
        {
            can[i][0]=1;//此时,定义可通过的点位为1;
        }
        else break;//如果不是,也就是说碰到马所在点位,即停止循环;
    }
    for(i=0;i<16;i++)
    {
        if(map[0][i]==1)
        {
            can[0][i]=1;
        }//同样的,在列上进行操作;
        else break;
    }
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            if(map[i][j]==1)//如果棋盘上点位值为1,代表其可通过的话;
                can[i][j]=can[i-1][j]+can[i][j-1];
        }
    }
    printf("%lld",can[n][m]);//输出可通过路径的条数;
    return 0;
}

2 养兔子(20 分)

#include<stdio.h>
int main()
{
    int n,i;
    scanf("%d",&n);
    long long a[90]={0,1,2};//数值超过int范围,所以用long long int。同时,运算可知第0天0只,第一天一只,第二天两只,第三天就开始有规律了,为昨天的加前天的;
    for(i=3;i<=n;i++)
    {
        a[i]=a[i-1]+a[i-2];
    }
    printf("%lld",a[n]);
    return 0;
}

3 母牛的故事 (20 分)

#include<stdio.h>
int main()
{
	int n,i;
	scanf("%d",&n);
    int a[55]={0,1,2,3,4};//由题易知,第0年0头,第一年1头,第二年2头...直到第五年开始,第一年买的小母牛也开始生产小母牛,所以从第五年开始有了规律,是上一年的加四年前的;
	for(i=5;i<=n;i++)
    {
        a[i]=a[i-1]+a[i-3];
    }
	printf("%d",a[n]);
	return 0;
}

4 黄金时代 (20 分)

#include<stdio.h>
#define k 0.6180339887//k是题中所给的数值;
int main()
{
	int n,i;
	scanf("%d",&n);
	int a[20]={0,5};//第一个数为5;
	for(i=1;i<=n;i++)
    {
        a[i+1]=a[i]/k+0.1;//这边需要注意,需要加0.1之后再取整才是所要的数值(比如说输入为3的时候,若不加0.1则输出数值为12,实际值应为13)通过计算可知,当输入数值为偶数时,可以得到正确的整数,而输入数值为奇数时,需要加0.1才可以得到正确的整数,所以我们就都加0.1即可;
    }
    printf("%d",a[n]);
	return 0;
}

5 骨牌铺方格(20 分)

#include<stdio.h>
int main()
{
	int n,i;
	long long a[60]={0,1,2,3};
	scanf("%d",&n);
	for(i=3;i<=n;i++)
	{
		a[i]=a[i-1]+a[i-2];
	}
	printf("%lld",a[n]);
	return 0;
}//从这个题往下都是一些很简单的数学题

6 爬楼梯 (20 分)

#include<stdio.h>
int main()
{
	int n,i;
	long long a[50]={0,1,2};
	scanf("%d",&n);
	for(i=3;i<=n;i++)
	{
		a[i]=a[i-1]+a[i-2];
	}
	printf("%lld",a[n]);
	return 0;
}

7 三国佚事——巴蜀之危 (20 分)

#include<stdio.h>
int main()
{
	int n,i;
	long long a[20]={0,0,1,2};
	scanf("%d",&n);
	for(i=4;i<=n;i++)
	{
		a[i]=(i-1)*(a[i-2]+a[i-1]);
	}
	printf("%lld",a[n]);
	return 0;
}

8 王小二切饼 (20 分)

#include<stdio.h>
int main()
{
	int n,i,a[100]={0,2};
	scanf("%d",&n);
	for(i=2;i<=n;i++)
	{
		a[i]=a[i-1]+i;//自己切一下找规律即可,每次切都要尽可能地于已有切线相交
	}
	printf("%d",a[n]);
	return 0;
}

9 蟠桃记 (20 分)

#include<stdio.h>
int main()
{
	int n,i,a[30]={1,4};
	scanf("%d",&n);
	for(i=2;i<n;i++)
	{
		a[i]=2*(a[i-1]+1);
	}
	printf("%d",a[n-1]);
	return 0;
 } 

10 C语言实验——拍皮球 (20 分)

#include<stdio.h>
int main()
{
    int t,n,i;
    double h,s;
    scanf("%lf %d",&h,&n);
    for(i=1;i<=n;i++)
    {
        if(i==1)
          s = h;
        else
       {
          s=s+(h*2.0);
       }
       h=h/2.0;
     }
    printf("%.2lf %.2lf",s,h);
    return 0;
} 

### 山东理工大学 PTA 平台递推问题解答示例 #### 后序和中序遍历输出先序遍历 对于给定的二叉树后序和中序遍历序列,可以利用递归方法构建并输出其前序遍历。以下是实现该功能的一个算法: 1. **核心思路** 利用后序遍历最后一个节点作为根节点,在中序遍历中找到对应的索引位置 `index`,从而将中序遍历划分为左子树和右子树两部分。 2. **代码实现** ```python def build_tree(postorder, inorder): if not postorder or not inorder: return [] root_val = postorder[-1] # 后序遍历的最后一个元素为根节点 index = inorder.index(root_val) # 找到根节点在中序中的位置 # 构建左子树和右子树 left_inorder = inorder[:index] right_inorder = inorder[index+1:] left_postorder = postorder[:len(left_inorder)] right_postorder = postorder[len(left_inorder):-1] # 递归处理左右子树 left_preorder = build_tree(left_postorder, left_inorder) right_preorder = build_tree(right_postorder, right_inorder) return [root_val] + left_preorder + right_preorder # 测试样例 postorder = [9, 3, 15, 20, 7] inorder = [9, 3, 15, 20, 7] preorder_result = build_tree(postorder, inorder) print(preorder_result) # 输出应为 [3, 9, 20, 15, 7] ``` 上述代码通过递归方式实现了从后序和中序遍历重建二叉树的过程,并最终返回前序遍历的结果[^1]。 --- #### 约瑟夫环问题递推解法 约瑟夫环问题是经典的递推问题之一,可以通过数学公式逐步缩小问题规模直至得到最终结果。 1. **核心公式** 假设当前有 `n` 个人围成一圈,每轮报数至 `m` 的人出列,则最后剩下的人的位置可以用如下递推关系表示: \[ f(n, m) = (f(n-1, m) + m) \% n \] 边界条件为 \( f(1, m) = 0 \),即当只剩一人时,此人编号为 0(基于零索引)。 2. **代码实现** ```python def josephus_problem(n, m): result = 0 for i in range(2, n + 1): # 从两人开始迭代 result = (result + m) % i return result # 测试样例 n_people = 5 step_size = 3 last_person_index = josephus_problem(n_people, step_size) print(last_person_index) # 输出应为 3 (基于零索引) ``` 此代码片段展示了如何通过递推公式高效解决约瑟夫环问题[^2]。 --- #### 归并排序的时间复杂度分析 归并排序是一种典型的分治算法,其时间复杂度可通过递推方程进行精确描述。 1. **递推方程** 设输入数组长度为 `n`,则归并排序的核心操作可由以下递推方程表达: \[ T(n) = 2T\left(\frac{n}{2}\right) + O(n) \] 这里,\(O(n)\) 表示合并两个有序子数组所需的线性时间开销。 2. **最优情况下的性能** 当每次划分都能均匀分割数组时,归并排序达到最佳效率,此时总运行时间为 \(O(n \log n)[^3]\)。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CRAEN

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值