【汉诺塔问题】UVa 10795 - A Different Task
【经典汉诺塔问题】
汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。在移动过程中可以利用B座,要求打印移动的步骤。如果只有一个盘子,则不需要利用B座,直接将盘子从A移动到C。
- 如果有2个盘子,可以先将盘子1上的盘子2移动到B;将盘子1移动到c;将盘子2移动到c。这说明了:可以借助B将2个盘子从A移动到C,当然,也可以借助C将2个盘子从A移动到B。
- 如果有3个盘子,那么根据2个盘子的结论,可以借助c将盘子1上的两个盘子从A移动到B;将盘子1从A移动到C,A变成空座;借助A座,将B上的两个盘子移动到C。这说明:可以借助一个空座,将3个盘子从一个座移动到另一个。
- 如果有4个盘子,那么首先借助空座C,将盘子1上的三个盘子从A移动到B;将盘子1移动到C,A变成空座;借助空座A,将B座上的三个盘子移动到C。
即:f(n)=f(n-1)+1+f(n-1)=(2^n)-1; f(1)=1;
代码如下:
#include <iostream>
#include <cstdio>
using namespace std; int step = ;
void move ( char sour, char dest )
{
printf ( "move from %c to %c \n", sour, dest);
}
void hanoi ( int n, char sour, char temp, char dest )
{
if (n == )
{
move (sour, dest);
++step;
}
else
{
hanoi ( n-, sour, dest, temp );
move (sour,dest);
++step;
hanoi ( n-, temp, sour, dest );
}
}
int main ()
{
int n = ;
hanoi ( n, 'A', 'B', 'C' );
printf ( "Total steps is %d\n", step );
return ;
}
【新汉诺塔问题】
给定初始局面和目标局面,求从初始局面到目标局面至少需要多少步。
分析:
- 参考局面:待移动盘子k在其初始柱子上且k上无其他盘子,k的目标柱子为空,中间柱子从上到下依次为1,2,...,k-1盘子。
- 首先找不在目标柱子上最大的盘子k,因为如果最大的盘子在目标柱子上它不需要移动,也不碍事。
- 剩下的任务与经典汉诺塔问题类似,即将k-1个盘子移到参考局面;将盘子k移到目标柱子;再将k-1个盘子移到目标局面(因移动是可逆的,故可看做是将目标局面的盘子移到参考局面)。可以看出这是个递归问题。
即我们需要一个函数f(P, i, final) : 将编号为1~i的盘子全部移到柱子final上所需要的步数(数组P表示各盘子的初始柱子编号,除去盘子的初始柱子x和最终柱子y剩下的那根柱子编号为6-x-y,因为只有柱子1,2,3);
则:ans = f(start,k-1,6-start[k]-finish[k])+f(finish,k-1,6-start[k]-finish[k])+1;
至于函数f的计算,当i为0时,无需移动;否则将1~i-1的盘子全部移到参考局面。若i-1号盘子本身在中转柱子上,那么就等同于只移动1~i-2号盘子到final柱子上。移动1~i-1号盘子由参考局面到目标局面的过程即为经典汉诺塔过程,步数为2^(i-1)-1;此处注意答案要用long long;
代码如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn = ;
int n, A[maxn], B[maxn];
//f(P, i, final) : 将编号为1~i的盘子全部移到柱子final上所需要的步数
//(数组P表示各盘子的初始柱子编号,除去盘子的初始柱子x和最终柱子y剩下的那根柱子编号为6-x-y)
long long f(int* P, int i, int fin)
{
if(!i) return ;
if(P[i] == fin) return f(P, i-, fin);
return f(P, i-, -P[i]-fin) + + ((1LL << (i-)) - );
}
int main()
{
int kase = ;
while(scanf("%d", &n) && n)
{
for(int i = ; i <= n; i++)
{
scanf("%d", &A[i]);
}
for(int i = ; i <= n; i++)
{
scanf("%d", &B[i]);
}
int k = n;
while(k && A[k] == B[k]) k--; long long ans = ;
if(k >= )
{
int tmp = -A[k]-B[k];
ans = f(A, k-, tmp) + + f(B, k-, tmp);
}
printf("Case %d: %lld\n", ++kase, ans);
}
return ;
}
【汉诺塔问题】UVa 10795 - A Different Task的更多相关文章
- UVA 10795 A Different Task(汉诺塔 递归))
A Different Task The (Three peg) Tower of Hanoi problem is a popular one in computer science. Briefl ...
- UVA 10254 - The Priest Mathematician (dp | 汉诺塔 | 找规律 | 大数)
本文出自 http://blog.csdn.net/shuangde800 题目点击打开链接 题意: 汉诺塔游戏请看 百度百科 正常的汉诺塔游戏是只有3个柱子,并且如果有n个圆盘,至少需要2^n- ...
- 算法笔记_013:汉诺塔问题(Java递归法和非递归法)
目录 1 问题描述 2 解决方案 2.1 递归法 2.2 非递归法 1 问题描述 Simulate the movement of the Towers of Hanoi Puzzle; Bonus ...
- C#递归解决汉诺塔问题(Hanoi)
using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace MyExamp ...
- 数据结构0103汉诺塔&八皇后
主要是从汉诺塔及八皇后问题体会递归算法. 汉诺塔: #include <stdio.h> void move(int n, char x,char y, char z){ if(1==n) ...
- Conquer and Divide经典例子之汉诺塔问题
递归是许多经典算法的backbone, 是一种常用的高效的编程策略.简单的几行代码就能把一团遭的问题迎刃而解.这篇博客主要通过解决汉诺塔问题来理解递归的精髓. 汉诺塔问题简介: 在印度,有这么一个古老 ...
- 几年前做家教写的C教程(之四专讲了指针与汉诺塔问题)
C语言学习宝典(4) 指针:可以有效的表示复杂的数据结构,能动态的分配动态空间,方便的使用字符串,有效的使用数组,能直接处理内存单元 不掌握指针就没有掌握C语言的精华 地址:系统为每一个变量分配一个内 ...
- python实现汉诺塔
经典递归算法汉诺塔分析: 当A柱子只有1个盘子,直接A --> C 当A柱子上有3个盘子,A上第一个盘子 --> B, A上最后一个盘子 --> C, B上所有盘子(1个) --&g ...
- fzu1036四塔问题(汉诺塔问题拓展)
#include<iostream> #include<cstdio> #include<cmath> using namespace std; ]; int ru ...
随机推荐
- CentOS7 安装98五笔输入法
86版的安装方式,网上找到一堆,折腾了很久才把98版的安装上,记录一下. 从这里下了这个 http://bbs.chinaunix.net/forum.php?mod=viewthread&t ...
- bzoj 3197 [Sdoi2013]assassin(Hash+DP+KM)
Description Input Output Sample Input 4 1 2 2 3 3 4 0 0 1 1 1 0 0 0 Sample Output 1 HINT [思路] Hash,D ...
- Hadoop文件系统常用命令
1.查看指定目录下内容 hadoop dfs –ls [文件目录] eg: hadoop dfs –ls /user/wangkai.pt 2.打开某个已存在文件 hadoop dfs –cat [f ...
- Bzoj 4591: [Shoi2015]超能粒子炮·改 数论,Lucas定理,排列组合
4591: [Shoi2015]超能粒子炮·改 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 178 Solved: 70[Submit][Stat ...
- linux下ssh使用rsa验证登陆MACOX
由于项目的需求,我这边ubuntu下常常需要SSH访问另外一台MACOS. 每次输入密码有点烦,就想到RSA公钥和密钥验证的方法. 像所有教程上讲的一样,本机执行 gong@hzsx:~$ ssh-k ...
- Tcp/Ip协议族简单解读及网络数据包/报/帧数据格式及封装及解包;
http://www.creseek.cn/products-install/install_on_bsd_linux/ 中文检索 离线cloudera ecosystem components: h ...
- 【组队训练】2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest
好多oj都崩掉了,于是打了cf.. 开始开的最后一题...尼玛题好长终于看完了...神题不会.... I过了好多人..看了下,一眼题...随便敲了下,1A ]; int main(){ int n, ...
- Activity的lanuchmode
假设: 假设栈有A-B-C-D,四个activity.其中D Activity在栈顶 standard: 此时跳转到D Activity,跳转后栈的情况是A-B-C-D-D singleTop: 此时 ...
- Delphi外挂开发网站
http://cheatengine.org/http://wenku.baidu.com/view/2d5de818964bcf84b9d57b15.html [delphi外G]http:// ...
- java类的访问控制符与其他几个特殊修饰符的总结
1 访问控制符 1.1 字段或者方法的访问控制符 同一个类中 同一个包中 不同包中的子类 不同包中的非子类 private YES 默认(包可访问) YES YES prot ...