poj1920

【题意】

给定一个汉诺塔的局面,问最少多少步可以将它们并到一个柱子上

【输入】

第一行n,表示n个盘子

接下来一行3个数字m[i],表示柱子上分别有几个盘子

随后的三行每行m[i]个数字,表示在该柱子上的盘子的编号

【输出】

第一行输出一个数字表示集中到哪个柱子上

第二行输出一个数字表示最小步数模1000000


汉诺塔的过程是可逆的,所以反过来考虑n个盘子都在一根柱子上最少需要移动多少步才能到达当前局面

既然倒过来了,那最底层的盘子就不要动了,所以最初的n个的盘子堆在n所在的柱子

然后从盘子编号从大到小考虑,假设当前i不在要到达局面的柱子上,那么就要将它所有上面的盘子移动到与它无关的柱子上,然后再将盘子i移到指定位置


program poj1920;
const
  maxn=1000000;
var
  ans,n,i,j,k,now:longint;
  two:array [0..100001] of longint;
  m:array [1..3] of longint;
  belong:array [0..100001] of longint;

begin
  two[0]:=1;
  for i:=1 to 100000 do
    two[i]:=two[i-1]*2 mod maxn;
  read(n);
  for i:=1 to 3 do
    read(m[i]);
  for i:=1 to 3 do
    for j:=1 to m[i] do
      begin
        read(k);
        belong[k]:=i;
      end;
  writeln(belong[n]);
  ans:=0;
  now:=belong[n];
  for i:=n downto 1 do
    if now<>belong[i] then
      begin
        ans:=(ans+two[i-1]) mod maxn;
        now:=6-belong[i]-now;
      end;
  writeln(ans);
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值