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;
}
没什么好说的,直接调用就行了。