题解 | 循环汉诺塔

循环汉诺塔

https://www.nowcoder.com/practice/cdf0808f841748faba058c8ef538c731

先自己在草稿纸上模拟了一下步骤,总结思路如下:

# 首先我们假设n个圆盘全部移动到B所需次数为L(n),全部到C为R(n)

# 一、对于全部移动到B的

# 1.首先前(n - 1)个一堆移动到C,该步骤次数为R(n - 1)

# 2.将n移动到B,操作1次

# 3.将前(n - 1)个一堆移动到B,该步骤次数为R(n - 1)

# 总次数L(n) = 2 * R(n - 1) + 1

# 二、对于全部移动到C的

# 1.首先前(n - 1)个一堆移动到C,该步骤次数为R(n - 1)

# 2.将n移动到B,操作1次

# 3.将前(n - 1)个一堆移动到A,该步骤次数为L(n - 1)

# 4.将n移动到C,操作1次

# 3.将前(n - 1)个一堆移动到C,该步骤次数为R(n - 1)

# 总次数R(n) = 2 * R(n - 1) + L(n - 1) + 2

于是,直接写出:

def L(n):
    if n == 1:
        return 1
    else:
        return 2 * R(n - 1) + 1

def R(n):
    if n == 1:
        return 2
    else:
        return 2 * R(n - 1) + L(n - 1) + 2
    
MOD = 10**9 + 7
def solve():
    n = int(input())
    print(L(n) % MOD, R(n) % MOD)
solve()

函数互相调用,时间复杂度O(2^n),这简直是左脚踩右脚想上天?

稍微修改一下:

MOD = 10**9 + 7
def solve():
    n = int(input())
    if n == 1:
        print(1, 2)
        return

    L_prev, R_prev = 1, 2
    for i in range(2, n + 1):
        L_curr = (2 * R_prev + 1) % MOD
        R_curr = (2 * R_prev + L_prev + 2) % MOD
        L_prev, R_prev = L_curr, R_curr
    print(L_prev, R_prev)
solve()

心想简直so eazy时间复杂度O(n)还过不了?

结果还真过不了...

转头用矩阵,快速进行幂计算:

MOD = 10**9 + 7
def matrix_mutl(A, B):
    return [
        [
            (A[0][0] * B[0][0] + A[0][1] * B[1][0] + A[0][2] * B[2][0]) % MOD,
            (A[0][0] * B[0][1] + A[0][1] * B[1][1] + A[0][2] * B[2][1]) % MOD,
            (A[0][0] * B[0][2] + A[0][1] * B[1][2] + A[0][2] * B[2][2]) % MOD,
        ],
        [
            (A[1][0] * B[0][0] + A[1][1] * B[1][0] + A[1][2] * B[2][0]) % MOD,
            (A[1][0] * B[0][1] + A[1][1] * B[1][1] + A[1][2] * B[2][1]) % MOD,
            (A[1][0] * B[0][2] + A[1][1] * B[1][2] + A[1][2] * B[2][2]) % MOD,
        ],
        [
            (A[2][0] * B[0][0] + A[2][1] * B[1][0] + A[2][2] * B[2][0]) % MOD,
            (A[2][0] * B[0][1] + A[2][1] * B[1][1] + A[2][2] * B[2][1]) % MOD,
            (A[2][0] * B[0][2] + A[2][1] * B[1][2] + A[2][2] * B[2][2]) % MOD,
        ],
    ]

def matrix_pow(mat, power):
    res = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    while power > 0:
        if power % 2 == 1:
            res = matrix_mutl(res, mat)
        mat = matrix_mutl(mat, mat)
        power //= 2
    return res

def solve():
    n = int(input())
    if n == 1:
        print(1, 2)
    else:
        M = [[0, 2, 1], [1, 2, 2], [0, 0, 1]]
        X_1 = [1, 2, 1]
        M_power = matrix_pow(M, n - 1)
        L_n = (M_power[0][0] * X_1[0] + M_power[0][1] * X_1[1] + M_power[0][2] * X_1[2]) % MOD
        R_n = (M_power[1][0] * X_1[0] + M_power[1][1] * X_1[1] + M_power[1][2] * X_1[2]) % MOD
        print(L_n, R_n)
solve()

不容易真不容易...

全部评论

相关推荐

07-03 16:02
门头沟学院 Java
点赞 评论 收藏
分享
05-26 22:25
门头沟学院 Java
Java小肖:不会是想叫你过去把你打一顿吧,哈哈哈
点赞 评论 收藏
分享
后来123321:别着急,我学院本大二,投了1100份,两个面试,其中一个还是我去线下招聘会投的简历,有时候这东西也得看运气
无实习如何秋招上岸
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务