问题描述
小F正在使用一个骑士跳跃方式的拨号器。这个拨号器是一个类似电话键盘的 3x4 矩阵,每个数字对应一个单元格,骑士只能站在蓝色数字单元格上进行跳跃(数字
1到9和0)。骑士的移动方式和国际象棋中的马相同:它可以垂直移动两个单元格并水平移动一个单元格,或水平移动两个单元格并垂直移动一个单元格,形成 "L" 形。123 456 789 *0#给定一个整数
n,你需要帮助小F计算骑士可以拨出的所有长度为n的不同电话号码的数量。骑士可以从任何数字开始,并在n-1次有效跳跃后得到一个有效号码。答案可能非常大,因此你需要返回对10^9 + 7取模的结果。
测试样例
样例1:
输入:
n = 1输出:10样例2:
输入:
n = 2输出:20样例3:
输入:
n = 3输出:46样例4:
输入:
n = 4输出:104
解题思路
-
考虑
0-9每个数字可以由哪些数字跳L型过来- 0: 4, 6
- 1: 6, 8
- 2: 7, 9
- 3: 4, 8
- 4: 0, 3, 9
- 5: 没有
- 6: 0, 1, 7
- 7: 2, 6
- 8: 1, 3
- 9: 2, 4
-
时,每个数字都是单独的,即
-
时,表示数字的组合数量,那么(根据上面来)
-
由于更新会导致后面使用产生变化,我们利用数组暂存,遍历完后更新
核心代码
int solution(int n) {
long long mod = 1e9+7;
vector<int>f(10,1);
for(int i = 1; i < n; i++) {
vector<int>t(10);
t[0] = (f[4] + f[6])%mod;
t[1] = (f[6] + f[8])%mod;
t[2] = (f[7] + f[9])%mod;
t[3] = (f[4] + f[8])%mod;
t[4] = (f[0] + f[3] + f[9])%mod;
t[6] = (f[0] + f[1] + f[7])%mod;
t[7] = (f[2] + f[6])%mod;
t[8] = (f[1] + f[3])%mod;
t[9] = (f[2] + f[4])%mod;
f = t;
}
int ans = 0;
for(int i = 0; i < f.size(); i++) ans = (ans + f[i]) % mod;
return ans;
}