目录
1.题目要求
2.题目解读
一道非常经典的题目,简洁易懂,但需要一定的数学思维,难点如下:
1.如何计算走法数?
这里需要我们运用数学思维,采用倒推法,每一次上楼梯可以走一步或两步,那么走n阶楼梯的走法数就等于(n-1)阶走法数与(n-2)阶走法数的和,只要想通这个问题就可以写出大致的代码框架啦~
2.如何解决大数加法,防止数据溢出
不知道大家有没有关注到题目的Hint
“对于100%的数据,1<=n<=5000”
经过刚刚的思考我们得知走n阶楼梯的走法数就等于(n-1)阶走法数与(n-2)阶走法数的和,那么如果n=5000,结果将会是......
显然这么大的数据就算是long long类型也无法储存,这时就会发生数据溢出,那我们该如何解决呢?
我在这里使用了高精度算法的思想,用二维数组模拟大数加法。(ps:感谢学长的指点~)
高精度算法:它是处理大数字的数学计算方法,在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除等运算。
思路:将这种大数字的每一位分别拆开,把每一位取出,存入数组中 ,变成用一个数组去存储每位的数字,最后再将数组进行相应的四则运算。
ps:这里要特别注意几个小点:(见代码注释)
1.进位的处理
2.正序运算,倒序输出
3.寻找结果中最高的非零位
3.代码实现
#include <stdio.h>
const int N=5001;
int a[5001][5001];//a[n][len]表示上n阶楼梯的走法数结果的第len位数字
void count(int n)
{
a[1][1]=1;
a[2][1]=2;//分别表示上 1 阶楼梯有 1 种走法,上 2 阶楼梯有 2 种走法
for(int i=3;i<=n;i++)
{
for(int j=1;j<=N;j++)
{
a[i][j]=a[i-2][j]+a[i-1][j];//上第i阶楼梯的走法数等于上i - 2阶和i - 1阶楼梯走法数之和
}
for(int j=1;j<=N;j++)//这个内层循环再次遍历每一位,用于处理进位
{
if(a[i][j]>=10)//进位操作
{
a[i][j+1]+=a[i][j]/10;
a[i][j]=a[i][j]%10;
}
}
}
}
int main()
{
int n;
scanf("%d",&n);
count(n);
int len=N;
while(len>=1&&a[n][len]==0) len--;//找到结果中最高的非零位,确定结果的有效位数范围
for(int i=len;i>=1;i--) printf("%d",a[n][i]);
return 0;
}
***新手博主创作不易,希望大家多多点赞关注呀~
标签:P1255,洛谷,走法,int,零位,len,C语言,题目,楼梯 From: https://blog.csdn.net/2402_86955314/article/details/143241460