1 题目描述
灵灵同学捉到了一只长出三对足的昆虫,把它放在了桌布上。恰好在昆虫的正前方有一条方格印花如下图所示。经过观察昆虫在桌布上的爬行发现,它的第一对足每次能前进一个方格,第二对足能前进两个方格,第三对足最为粗壮有力,一次可以前进三个方格。前进的每一步只有一对足发力。现在请你帮助灵灵计算一下,到达指定的方格n,可以有多少种不同的走法?
输入
输入只有一行,包括一整数n(0 < n< 70)。
输出
输出只有一行,为走法的数目。
样例输入 Copy
3
样例输出 Copy
4
提示
样例说明
到达第三个格子的方法可以是:
每步走一格:1→2→3,
先走一格,再走两格:1→3,
先走两格,再走一格:2→3,
走三格:3;
共4种走法。
对于40%的数据,n<5;
对于100%的数据,0<n<70。
【说明】编程题目常常会有大量无关的信息,比如上面的题目描述,真正有用的信息只有蓝色字体部分。要学会迅速抓住题目主干,也是练习编程该给我这方面能力的训练。
2 题目分析
这是一个典型的递归问题
根据题目描述和样例提示,甲壳虫每一步只有走1、2、3个格子三种可能,我们可以得到:
(1)当n等于1,甲壳虫只可能走一步到达终点(终点就是第一个格子);
(2)当n等于2,甲壳虫到达终点的方式有两种:
- 先走一个格子,再走一个格子,到达终点;
- 直接走两个格子,到达终点;
(3)当n等于3,甲壳虫到达终点的方式有4种(也就是样例给出的):
样例说明
到达第三个格子的方法可以是:
每步走一格:1→2→3,
先走一格,再走两格:1→3,
先走两格,再走一格:2→3,
走三格:3;
共4种走法。
(4)当n等于4,从这里开始就是递归了,由于甲壳虫每一步只有走1、2、3个格子三种可能,所以这个地方要分情况(最终的答案为所有情况的走法数目的和),第一步它可以走1个格子(下一步还剩下3个格子),也可以走2个格子(下一步还剩下2个格子),也可以走3个格子(下一步还剩下1个格子),问题也就演变为求子问题的和,假设用F(n)表示走到第n个格子有多少种走法,那么F(4)就等于F(3)+F(2)+F(1)了!即 F(n) = F(n-1) + F(n-2) + F(n-3) !
3 分析到这里,这个问题的解法就出来了
(1)当n等于1,F(n) = 1;
(2)当n等于2,F(n) = 2;
(3)当n等于3,F(n) = 4;
(4)当n等于4,F(n) = F(3) + F(2) + F(1) = 7 种
.................
(5)当n等于n,F(n) = F(n-1) + F(n-2) + F(n-3)
4 代码如下
// Created by Liu Xianmeng on 2022/11/3
#include <bits/stdc++.h>
using namespace std;
typedef long long LL; // 返回的结果可能很大 用LL接收
// 获取走到第n个格子总共有多少种走法
LL getMoves(LL n){
if(n == 1){
return 1;
}else if(n == 2){
return 2;
}else if(n == 3){
return 4;
}else{
return getMoves(n-1) + getMoves(n-2) + getMoves(n-3);
}
}
int main() {
int n;
cin>>n;
cout<<getMoves(n);
return 0;
}
代码没有问题,但是在日常的竞赛题目中,可能会运行超时或者内存超限无法通过,所以,用迭代法运行时间会更短:
// 获取走到第n个格子总共有多少种走法
LL getMoves2(LL n){
if(n == 1){
return 1;
}else if(n == 2){
return 2;
}else if(n == 3){
return 4;
}else{
LL sum1 = 1;
LL sum2 = 2;
LL sum3 = 4;
LL sum4;
for(int i=4; i<=n; ++i){
/** 求出当前i对应的总步数 **/
sum4 = sum1 + sum2 + sum3;
/** 迭代更新 **/
sum1 = sum2;
sum2 = sum3;
sum3 = sum4;
}
return sum4;
}
}
>.< ~