N阶楼梯上楼问题

题目描述
N阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式。(要求采用非递归)

注意点
1、自定义函数返回结果为矩阵时,最好将需要返回的结果作为参数放在函数名中;
2、数据爆炸问题,在本题中,简单用long long 类型代替int类型加以解决。

#include <stdio.h>
#include <string.h>

/****************************
**功能:两个矩阵相乘
**参数说明:两个矩阵分别为a(l*m)矩阵,b(m*n)矩阵,结果为矩阵,返回结果放在形参中。
*****************************/
void multiMatrix(long long res[][2],long long a[][2],long long b[][2],int l,int m,int n)
{
    int i,j,x;
    for(i=0;i<l;i++)
        for(j=0;j<n;j++)
        {
            res[i][j]=0;
            for(x=0;x<m;x++)
            {
                res[i][j]+=a[i][x]*b[x][j];

            }

//            printf("%lld ",res[i][j]);

        }
//        printf("\n");
}

/****************************
**功能:求某矩阵a的n次方
**参数说明:矩阵a是x*x的矩阵,求n次方
*****************************/
void powerMatrix(long long res[][2],long long a[][2],int x,int n)
{
    int i,j;
    long long temp[2][2];
    //初始化为单位矩阵
    for(i=0;i<x;i++)
        for(j=0;j<x;j++)
        {
            if(i==j)
                res[i][j]=1;
            else
                res[i][j]=0;
        }
    for(;n!=0;n>>=1)
    {
        if(n&1!=0)
        {
//            printf("1\n");
            multiMatrix(temp,res,a,2,2,2);
            memcpy(res,temp,4*sizeof(long long));
        }
//        printf("累乘\n");
        multiMatrix(temp,a,a,2,2,2);
        memcpy(a,temp,4*sizeof(long long));
    }
}

/****************************
**功能:非递归函数求爬楼梯方法数
**参数说明:num:楼梯阶数,使用long long,防止在n>46时,出现数据爆炸
*****************************/
long long func(int num)
{
    long long base[2][2]={{1,1},{1,0}};
    long long res[2][2];
    int i,j;
    if(num==1)
        return 1;
    if(num==2)
        return 2;
    powerMatrix(res,base,2,num-2);
    return 2*(res[0][0])+res[1][0];
}

/****************************
**功能:主函数
*****************************/
int main()
{
    int num;
    while(scanf("%d",&num)!=EOF)
    {
        printf("%lld\n",func(num));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值