PAT乙级(Basic Level)练习题 骨牌铺方格

题目描述
在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出铺放方案的总数.

例如n=3时,为2× 3方格,骨牌的铺放方案有三种,如下图:
在这里插入图片描述
输入描述:
输入数据由多行组成,每行包含一个整数n,表示该测试实例的长方形方格的规格是2×n (1≤n≤90)。

输出描述:
对于每个测试实例,请输出铺放方案的总数,每个实例的输出占一行。

输入例子:

1
3
2

输出例子:

1
3
2

: \color{red}解题思路:
乍一看,感觉有些复杂,想着用递推的思路,比如n = 2时
在这里插入图片描述
当n = 3时,
在这里插入图片描述
当n = 4时,可有n=2、n=3进行扩展
在这里插入图片描述
在这里插入图片描述
如果这样想,确实很复杂,因为存在很多的重复项,可能需要记住所有的状态进行比较。说明我们得思路不对。

经过上面的画图,我们知道f(2) = 2,f(3) = 3, f(4)=5,而n=4确实可有n=2、n=3进行扩展。从数字中可知f(4) = f(2) + f(3),那会不是斐波拉契尔数列呢?

其实你可以手动画一下f(5),确实会发现是斐波拉契尔数列问题。我们前面由n=2、n=3推n=4时,思路是正确的,但是我们进行扩展的时候进行排列(插入不同的位置)。其实n=3也是有n=1、n=2推出的,即本来n=1、n=2、n=3就存在内如的逻辑关系。

可能有部分道友会说我这是瞎猜的,没有直接证明f(n) = f(n - 1) + f(n - 2)(n ≥ 2),我也有点无奈,这个确实有点难证明。

在前一道爬楼梯的问题 PAT乙级(Basic Level)练习题 童年生活二三事,与此道题非常相似,横向摆放相当于跨2阶楼梯,纵向增加相当于跨1阶楼梯。

: \color{red}代码实现:

#include <iostream>
using namespace std;

int main(int argc, const char * argv[]) {
    //建立一张表,用于记录f(n)各项值,注意数据溢出,使用long long型
    long long fTable[91] = {0, 1, 2};
    for (int i = 3; i < 91; ++i) {
        fTable[i] = fTable[i - 1] + fTable[i - 2];
    }
    int number = 0;
    //scanf返回值为正确输入数据的变量个数,当一个变量都没有成功获取数据时,此时返回-1
    while (scanf("%d", &number) != - 1) {
        printf("%lld\n", fTable[number]);
    }
    return 0;
}

在这里插入图片描述

发布了1005 篇原创文章 · 获赞 269 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/104639245
今日推荐