UVA 10795打卡

算法竞赛入门经典训练指南打卡

题目链接:UVa 10795

思路

对于汉诺塔问题,首先需要做的是将大的盘子移动到目标位置
所以我们应该首先找到大的盘子进行判断,如果大的盘子在目标位置上,则不动,如果不在则要先移动大的盘子
因此首先找到最大的不在目标位置的盘子
然后如书上提供的思路算出初始局面移动到参考局面和目标局面移动到参考局面的步数之和再加1即为最终结果
具体的细节看代码注释

代码如下:

#include <iostream>
#define LL long long
#define ton(i , n) for(int i = 1 ; i <= n ; ++ i)

using namespace std ;

LL step(int *p , int k , int final){
    if(k == 0)
        return 0 ;      //已经移动完了
    if(p[k] == final)
        return step(p , k - 1 , final) ;        //当前的盘子已经在中转站了,移动其余比它小的盘子到中转站
    return step(p , k - 1 , 6 - p[k] - final) + ((LL)1 << (k - 1)) ;
        //将该盘子移动到中转站,比它小的所有盘子要先移动到其他柱子上面,它上面不可以有盘子,中转站上也不可以有比它小的盘子
        //步数则是将其他盘子先移动到其他柱子上所需要的步数再加上他和其他盘子都移动到中转站的步数
}

int start[65] , finish[65] ;

int main(){
    int kase = 1 , n ;
    while (cin >> n && n){
        ton(i , n)
            cin >> start[i] ;       //输入初始局面
        ton(i , n)
            cin >> finish[i] ;      //输入目标局面
        int k = n ;
        while (k >= 1 && start[k] == finish[k])
            k -- ;      //找到需要移动的最大的盘子
        LL ans = 0 ;
        if(k >= 1){
            int other = 6 - start[k] - finish[k] ;      //找到中转站,即除了目标位置和初始位置的另一根柱子
            ans = step(start , k - 1 , other) + step(finish , k - 1 , other) + 1 ;      //计算结果
        }
        cout << "Case " << kase ++ << ": " << ans << endl ;
    }
    return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值