Hello! 欢迎来到Yearcode!

百度之星 还原汉诺塔 2024


avatar
lht006128 2025-06-28 17

题目分析

简单分析下题目,题目告诉你有三个杆子A B C
目标是让所有盘子到C
给你有多少个盘子和 当前走到了哪一步,要你求现在每一个盘子在哪个杆子上面。

思路

汉诺塔问题是一个很经典的递归问题,当然这题我们也可以用递归来解决。
递归主要分析相邻的步骤,而不是全局去看,不然很容易乱,所以我们先从最下面的盘开始分析(这样好分析)。 因为我们可以利用公式 和二进制结合。

我们要把第一个放到C 就得把 上面所有的先放到B 也就是 对于最后一个 目标盘是 C 中转盘是B 而对于上面的 目标盘是B 中转盘是C;

这里得注意并非所有盘终点盘都是C ,这得看情况的
下面的解释我不在用ABC 去描述杆 而是用目标 转中 起始 去描述

怎么知道最下面的能不能到目标盘? 根据公式 ,如果我们把n个盘移到目标杆 需要2^n -1 步
同理 如果我们要把 上面的盘移到中转杆 需要2^n-1 -1 步,然后把自己移到目标杆就在加一。
因为是2的多少次方,就可以从步数的二进制看出来能不能把上面的移走 然后 自己到目标杆

假设可以 ,那么 答案加一个 他的目标杆 字符

然后遍历他上一个盘,因为对于上面的盘他们现在在B杆 B杆变成起始杆了,A变初始杆 。
交换字符 A B
然后以此类推 即可

如果该盘不可以到目标杆,那么对于上面的盘,他们现在的目标杆还是底部盘的中转杆,所以往上遍历要交换 中转杆和 目标杆。

上面这个过程很巧妙,需要自己好好想想。

AC 代码

#include<bits/stdc++.h>
using namespace std;

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n;
    string s;
    cin>>n>>s;
    char S= 'A',M='B',E='C';
    string ans;

    for(int i=0;i<s.size();i++){
        if(s[i]=='1'){
            ans+=E;
            swap(M,S);
        }else{
            ans+=S;
            swap(M,E);
        }
    }
    reverse(ans.begin(),ans.end());
    cout<<ans;

}

暂无评论

发表评论
Yearcode Blog