洛谷P1255数楼梯题解(高精加与容器与递归)

1.审题

  • 对于 100%的数据,1≤N≤5000。这显然已经超过了long long的范围
  • 走楼梯原理不就是斐波那契数列嘛。很简单,难点在于怎么把高精加和递归结合在一起

2.先写递归

// 计算楼梯不同走法的递归函数
std::vector<int> stairWays(int N) {
    if (N == 1) {
        //相当于创建一个临时容器,容纳第一个数1
        std::vector<int> result = { 1 };
        return result;
    }
    else if (N == 2) {
        //相当于创建一个临时容器,容纳第二个数2
        std::vector<int> result = { 2 };
        return result;
    }
    else {
        std::vector<int> a = { 1 };
        std::vector<int> b = { 2 };
        for (int i = 3; i <= N; i++) {
            //容器temp是a+b的值,是第i个台阶的所有走法
            std::vector<int> temp = add(a, b);
            //容器a=容器b,相当于往右移动一位
            a = b;
            //把b往右挪一位;
            b = temp;
        }
        return b;
    }
}

和小数据量的解法一样,在N位1和2时我们直接输出1和2就好了,当N大于2的时候,我们把a作为第一个值,b作为第二个值,创建一个临时的vector,接收a和b相加的返回值(这是我们要实现的高精加法),执行完后,a要向右挪一个,b也要向右挪一个,也就是等于它两相加的值,这个式子从3开始(因为1和2已知),已知循环加到N,这样就可以得到我们的结果了。

3.实现高精加

传统的高精加函数,不仅要传入数组指针,还有,倒序,初始化等一系列操作。我们使用vector加&就可以省去很多的麻烦。

std::vector<int> add(std::vector<int>& a, std::vector<int>& b) {
    //carry是进位
    int carry = 0;
    //创建一个存储加和后的容器
    std::vector<int> result;
    int i = 0;
    while (i < a.size() || i < b.size() || carry) {
        //从低位开始加
        if (i < a.size()) {
            carry += a[i];
        }
        if (i < b.size()) {
            carry += b[i];
        }
        //余数放在低位
        result.push_back(carry % 10);
        //进位带到下一位
        carry /= 10;
        i++;
    }
    return result;
}

在上面的代码中我们使用了一个临时容器来接收add函数的返回值,并传入了两个容器,所以我们返回值类型要是两个容器,然后配合引用来接收我们的容器。从a[0]和b[0]开始加,加完后%10得到个位数放在result容器里头,carry就相当于存储进位这么一个东西,当它/10后剩下的就是要进到下一位的值,循环上去再进行下一位的加和。

4.主函数 

 

int main() {
    int N;
    std::cin >> N;
    //创建了一个ways容器并将stairWays函数的结果储存在里面;
    std::vector<int> ways = stairWays(N);
    //size()计算的是容器中的元素个数-1得到最大元素的下标;
    for (int i = ways.size() - 1; i >= 0; i--) {
        std::cout << ways[i];
    }
    return 0;
}

 

没什么好说的,直接调用就行了。 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值