2017.2.09【初中部 提高组】模拟赛C组 汉诺塔 题解

原题:

http://172.16.0.132/junior/#contest/show/1373/1

题目描述:

古老的汉诺塔问题是这样的:用最少的步数将N个半径互不相等的圆盘从1号柱利用2号柱全部移动到3号柱,在移动的过程中小盘要始终在大盘的上面。
现在再加上一个条件:不允许直接把盘从1号柱移动到3号柱,也不允许直接把盘从3号柱移动到1号柱。
把盘按半径从小到大用1到N编号。每种状态用N个整数表示,第i个整数表示i号盘所在的柱的编号。则N=2时的移动方案为:
(1,1)=>(2,1)=>(3,1)=>(3,2)=>(2,2)=>(1,2)=>(1,3)=>(2,3)=>(3,3)
初始状态为第0步,编程求在某步数时的状态。

输入:

输入文件的第一行为整数T(1<=T<=50000),表示输入数据的组数。
接下来T行,每行有两个整数N,M(1<=n<=19,0<=M<=移动N个圆盘所需的步数)。

输出:

输出文件有T行。
对于每组输入数据,输出N个整数表示移动N个盘在M步时的状态,每两个数之间用一个空格隔开,行首和行末不要有多余的空格

样例输入:

4
2 0
2 5
3 0
3 1

样例输出:

1 1
1 2
1 1 1
2 1 1

分析:

本题仍然可以使用经典汉诺塔问题的算法来解决。
在经典汉诺塔问题中,算法分为3步:
1、将最小的n-1个盘从a移到b
2、将最大的第n个盘从a移到c
3、将最小的n-1个盘从b移到c
递归方程 f[n]=f[n-1]+1+f[n-1]
而,新的汉诺塔问题由于新的限制,算法分为5步:
1、将最小的n-1个盘从a移到c
2、将最大的第n个盘从a移到b
3、将最小的n-1个盘从c移到a
4、将最大的第n个盘从b移到c
5、将最小的n-1个盘从a移到c
因此,新的递归方程f[n]=f[n-1]+1+f[n-1]+1+f[n-1];

实现:

var
        f,ans:array[0..21]of int64;
        i:longint;
        t,m,n:int64;
procedure move(n,m,t1,t2,t3:int64);
begin
        if n=0 then exit;
        if m<=f[n-1] then
        begin
                ans[n]:=t1;
                move(n-1,m,t1,t2,t3);
                exit;
        end;
        if m<=f[n-1]+1+f[n-1] then
        begin
                ans[n]:=t2;
                move(n-1,m-(f[n-1]+1),t3,t2,t1);
                exit;
        end;
        ans[n]:=t3; move(n-1,m-(f[n-1]+1+f[n-1]+1),t1,t2,t3);
end;
begin
        assign(input,'hanoi.in');reset(input);
        assign(output,'hanoi.out');rewrite(output);
        f[0]:=0;
        for i:=1 to 19 do f[i]:=f[i-1]+1+f[i-1]+1+f[i-1];
        readln(t);
        while t>0 do
        begin
                readln(n,m);
                move(n,m,1,2,3);
                write(ans[1]);
                for i:=2 to n do write(' ',ans[i]);
                writeln;
                dec(t);
        end;
        close(input);close(output);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值