其他分享
首页 > 其他分享> > NC14585 大吉大利,今晚吃鸡

NC14585 大吉大利,今晚吃鸡

作者:互联网

NC14585 大吉大利,今晚吃鸡

题目

题目描述

糖和抖m在玩个游戏,规定谁输了就要请谁吃顿大餐:抖m给糖a b c三个驻, 并在a柱上放置了数量为n的圆盘,圆盘的大小从上到下依次增大,现在要做的事就是把a柱的圆盘全部移到c柱,移动的过程中保持小盘在上,大盘在下,且限定圆盘只能够移动到相邻的柱子,即a柱子上的圆盘只能够移动到b,b柱子上的圆盘只能够移动到a或者c,c同理。现在请你设计一个程序,计算所需移动的最小步数, 帮助糖赢得大餐!

输入描述

每一行输出有一个整数 \(n\) \((0\leq n<26)\), 直至文件末尾。

输出描述

对于每一组数据,输出一行,输出移动的最小步数 \(M\)。

示例1

输入

1

输出

2

题解

思路

知识点:递归,思维。

与普通的汉诺塔不同的是,此汉诺塔的 \(f(n)\) 表示的 \(A\) 到 \(C\) 的两步而不是一步。过程如下:

  1. 把 \(n-1\) 个圆盘从 \(A\) 移到 \(B\) 再移到 \(C\) 走了 \(f(n-1)\) 步
  2. 把第 \(n\) 个盘子从 \(A\) 移到 \(B\) 走了一步
  3. 把 \(n-1\) 个圆盘从 \(C\) 移到 \(B\) 再移到 \(A\) 走了 \(f(n-1)\) 步
  4. 把第 \(n\) 个盘子从 \(B\) 移到 \(C\) 走了一步
  5. 把 \(n-1\) 个圆盘从 \(A\) 移到 \(B\) 再移到 \(C\) 走了 \(f(n-1)\) 步

于是有递推公式 \(f(n) = 3f(n-1) + 2\) 。

解得 \(f(n) = 3^n-1\) 。

时间复杂度 \(O(\log n)\)

空间复杂度 \(O(1)\)

代码

#include <bits/stdc++.h>
#define ll long long

using namespace std;

/* long long cnt;
void hanoi2(char A, char B, char C, int n) {
    if (n == 1) {
        cout << "Step " << ++cnt << ": " << A << " -> " << B << '\n';
        cout << "Step " << ++cnt << ": " << B << " -> " << C << '\n';
        return;
    }
    hanoi2(A, B, C, n - 1);
    cout << "Step " << ++cnt << ": " << A << " -> " << B << '\n';
    hanoi2(C, B, A, n - 1);
    cout << "Step " << ++cnt << ": " << B << " -> " << C << '\n';
    hanoi2(A, B, C, n - 1);
} */ ///这里的f(n) 指从A到C的两步

ll qpow(ll a, int k) {
    ll ans = 1;
    while (k) {
        if (k & 1) ans = ans * a;
        k >>= 1;
        a = a * a;
    }
    return ans;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;
    while (cin >> n) {
        //cnt = 0;
        //hanoi2('A', 'B', 'C', n);
        //cout << cnt << '\n';
        cout << qpow(3, n) - 1 << '\n';
    }
    return 0;
}

标签:cout,今晚,圆盘,long,char,int,大吉大利,NC14585,移动
来源: https://www.cnblogs.com/BlankYang/p/16403783.html