垃圾博主,在线抄作业
骑士拨号器
题目
国际象棋中的骑士可以按下图所示进行移动:
这一次,我们将 “骑士” 放在电话拨号盘的任意数字键(如上图所示)上,接下来,骑士将会跳 N-1 步。每一步必须是从一个数字键跳到另一个数字键。
每当它落在一个键上(包括骑士的初始位置),都会拨出键所对应的数字,总共按下 N
位数字。
你能用这种方式拨出多少个不同的号码?
因为答案可能很大,所以输出答案模 10^9 + 7
。
菜鸡做题步骤
当然,是看了题解再来写的代码。
首先,还是得手算前几种情况,以更好地理解这个问题(我后来手算时才发现我对解答还是有错误的理解的)。
1 | class Solution { |
看到矩阵快速幂,虽然不懂他的意思,但想到可以用矩阵来解决这个问题:
竖着的代表每一个按键,横着代表当前案件跳一次可以到达的按键。
只需用这个矩阵N次左乘就能得到 按N次的所有情况中,最后一位是X(X为0~4、6~9)的次数 的矩阵。
大佬题解1
在N>=2时,除数字5以外的9个数字都是可到达的。
每跳一步,数字的变化如图所示:
图片表示,当骑士处于“1”处时,下一跳将在“6”或“8”;骑士处于“4”处时,下一跳将在“3”或“0”或”9”;骑士处于“0”处时,下一跳将在“4”或“6”…………
我们可以发现,1、3、7、9处于对称位置;2,8处于对称位置;4,6处于对称位置。因此,我们可以将数字分为4个状态,命名为A、B、C、D。其中A:{1,3,7,9},B:{2,8},C:{4,6},D:{0}。
我们用f(X,n)表示:在状态X下,跳跃n步能够得到不同数字的个数。则状态转移方程为:
1 | f(A,n)=f(B,n-1)+f(C,n-1) |
解释为:
处于状态A中的数字(1,3,7,9)通过一次跳跃要么变成状态B(2,8),要么变成状态C(4,6)
处于状态B中的数字(2,8)通过一次跳跃有两种方式变成状态A(1,3,7,9)
处于状态C中的数字(4,6)通过一次跳跃有两种方式变成状态A(1,3,7,9),还有一种方式变成状态D(0)
处于状态D中的数字(0)通过一次跳跃有两种方式变成状态C(4,6)
通过迭代,我们即可求解。
代码
1 | class Solution: |
复杂度分析
- 时间复杂度:$O(n)$
- 空间复杂度:$O(1)$
矩阵快速幂
如果我们把上面的状态转移过程使用矩阵来表示的话,那么我们可以得到这个式子:
$$
\begin{bmatrix}
A\\
B\\
C\\
D\\
\end{bmatrix}=
\begin{bmatrix}
0 & 1 & 1 & 0\\
2 & 0 & 0 & 0\\
2 & 0 & 0 & 1 \\
0 & 0 & 2 & 0 \\
\end{bmatrix}^{n-1}
\begin{bmatrix}
1\\
1\\
1\\
1\\
\end{bmatrix}
$$
其中,A、B、C、D代表在n-1次迭代结束后,处于状态A、B、C、D的可能个数。
最终的答案即为(4*A+2*B+2*C+D)%1000000007
复杂度分析
- 时间复杂度:$O(log(n))$ (由于矩阵快速幂的时间复杂度为O(log(n)) )
- 空间复杂度:$O(1)$