zoj 2338 The Towers of Hanoi Revisited
The Towers of Hanoi Revisited
Time Limit: 5 Seconds Memory Limit: 32768 KB Special Judge
You all must know the puzzle named ��The Towers of Hanoi��. The puzzle has three pegs and N discs of different radii, initially all disks are located on the first peg, ordered by their radii - the largest at the bottom, the smallest at the top. In a turn you may take the topmost disc from any peg and move it to another peg, the only rule says that you may not place the disc atop any smaller disk. The problem is to move all disks to the last peg making the smallest possible number of moves.
There is the legend that somewhere in Tibet there is a monastery where monks tirelessly move disks from peg to peg solving the puzzle for 64 discs. The legend says that when they finish, the end of the world would come. Since it is well known that to solve the puzzle you need to make 2N - 1 moves, a small calculation shows that the world seems to be a quite safe place for a while.
However, recent archeologists discoveries have shown that the things can be a bit worse. The manuscript found in Tibet mountains says that the puzzle the monks are solving has not 3 but M pegs. This is the problem, because when increasing the number of pegs, the number of moves needed to move all discs from the first peg to the last one following the rules described, decreases dramatically. Calculate how many moves one needs to move N discs from the first peg to the last one when the puzzle has M pegs and provide the scenario for moving the discs.
This problem contains multiple test cases!
The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.
The output format consists of N output blocks. There is a blank line between output blocks.
Input
Input file contains N and M (1 <= N <= 64, 4 <= M <= 65).
Output
On the first line output L - the number of moves needed to solve the puzzle. Next L lines must contain the moves themselves. For each move print the line of the form
move <disc-radius> from <source-peg> to <target-peg>
if the disc is moved to the empty peg or
move <disc-radius> from <source-peg> to <target-peg> atop <target-top-disc-radius>
if the disc is moved atop some other disc.
Disc radii are integer numbers from 1 to N, pegs are numbered from 1 to M.
Sample Input
1
5 4
Sample Output
13
move 1 from 1 to 3
move 2 from 1 to 2
move 1 from 3 to 2 atop
2
move 3 from 1 to 4
move 4 from 1 to 3
move 3 from 4 to 3 atop
4
move 5 from 1 to 4
move 3 from 3 to 1
move 4 from 3 to 4 atop
5
move 3 from 1 to 4 atop 4
move 1 from 2 to 1
move 2 from 2 to 4 atop
3
move 1 from 1 to 4 atop 2
汉诺塔问题,了解一个公式。记f[n][m]为n个disc,m个peg的Hanoi问题,则有dp公式f[n][m]=min{f[n-k][m-1]+2*f[k][m]}。即把上面的k个disc利用m个peg转移某个中间peg,再把下面的n-k个disc利用m-1个peg转移到目标peg,最后把上面的k个disc利用m个peg移到目标peg。dp过程记下使得f[n][m]最小的g[n][m]=k用于反向打印移动过程。
题意:给定N(1<= N <=64)个盘子和M(4<= M <= 65)根柱子,问把N个盘子从1号柱子移动到M号柱子所需要的最少步数,并且输出移动过程。
附上代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std; typedef unsigned long long ll;
const ll INF=;
ll dp[][];
int pre[][];
int n,m;
stack<int>v[];
bool w[]; void move(int a,int b) //从a这根柱子移到b这跟柱子
{
if(v[b].empty()) printf("move %d from %d to %d\n",v[a].top(),a,b);
else printf("move %d from %d to %d atop %d\n",v[a].top(),a,b,v[b].top());
v[b].push(v[a].top());
v[a].pop();
return;
} void DFS(int ct,int a,int b,int h) //ct 表示盘子个数 a,b表示柱子标号 通过h根的柱子来进行操作
{
int i,j;
if(ct==)
{
move(a,b);
return;
}
for(i=; i<=m; i++)
if(i!=a && i!=b && !w[i]) break;
DFS(pre[ct][h],a,i,h);
w[i]=;
DFS(ct-pre[ct][h],a,b,h-);
w[i]=;
DFS(pre[ct][h],i,b,h);
} void init()
{
int i,j,k;
for(i=; i<=; i++) //最少三根柱子,才可以开始移动,从这里开始记录数据
{
dp[i][]=*dp[i-][]+;
pre[i][]=i-;
}
for(i=; i<=; i++) //柱子
{
dp[][i]=;
for(j=; j<; j++) //盘子
{
ll t=INF;
for(k=; k<j; k++) //先移走k个盘子到一个中间柱子,剩下j-k盘子移动到目标
{
if(t>dp[j-k][i-]+*dp[k][i])
{
t=dp[j-k][i-]+*dp[k][i];
pre[j][i]=k;
}
}
dp[j][i]=t;
}
}
} int main()
{
int i,j,T;
init();
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
printf("%lld\n",dp[n][m]);
for(i=; i<=m; i++) while(!v[i].empty()) v[i].pop(); //初始数据为空
for(i=n; i>=; i--) v[].push(i);
memset(w,,sizeof(w));
DFS(n,,m,m);
}
return ;
}
zoj 2338 The Towers of Hanoi Revisited的更多相关文章
- ZOJ-2338 The Towers of Hanoi Revisited 输出汉诺塔的最优解移动过程
题意:给定N(1<= N <=64)个盘子和M(4<= M <= 65)根柱子,问把N个盘子从1号柱子移动到M号柱子所需要的最少步数,并且输出移动过程. 分析:设f[i][j] ...
- SGU 202 The Towers of Hanoi Revisited (DP+递归)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题意 :n个圆盘,m个柱子的汉诺塔输出步骤. ht ...
- SGU 202. The Towers of Hanoi Revisited
多柱汉诺塔问题. 引用自wiki百科 多塔汉诺塔问题 在有3个柱子时,所需步数的公式较简单,但对于4个以上柱子的汉诺塔尚未得到通用公式,但有一递归公式(未得到证明,但目前为止没有找到反例): 令为在有 ...
- The Towers of Hanoi Revisited---(多柱汉诺塔)
Description You all must know the puzzle named "The Towers of Hanoi". The puzzle has three ...
- [CareerCup] 3.4 Towers of Hanoi 汉诺塔
3.4 In the classic problem of the Towers of Hanoi, you have 3 towers and N disks of different sizes ...
- POJ 1958 Strange Towers of Hanoi 解题报告
Strange Towers of Hanoi 大体意思是要求\(n\)盘4的的hanoi tower问题. 总所周知,\(n\)盘3塔有递推公式\(d[i]=dp[i-1]*2+1\) 令\(f[i ...
- POJ 1958 Strange Towers of Hanoi
Strange Towers of Hanoi Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 3784 Accepted: 23 ...
- POJ-1958 Strange Towers of Hanoi(线性动规)
Strange Towers of Hanoi Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 2677 Accepted: 17 ...
- ural 2029 Towers of Hanoi Strike Back (数学找规律)
ural 2029 Towers of Hanoi Strike Back 链接:http://acm.timus.ru/problem.aspx?space=1&num=2029 题意:汉诺 ...
随机推荐
- bzoj2467 生成树
传送门 生成树计数裸题,因为模数不是质数所以要用辗转相除的高斯消元. de了很久的bug然后发现一个变量A赋值后下一行又申明了一个新的临时变量A(: //Achen #include<algor ...
- svn基本命令使用
1.svn help:可以通过该命令查看svn的所有操作命令,包括命令的缩写 2.首先需要从svn库中checkout对应的项目: (1)svn项目路径为svn://192.168.1.1/mypro ...
- LintCode 删除排序链表中的重复元素
给定一个排序链表,删除所有重复的元素每个元素只留下一个. 样例 给出 1->1->2->null,返回 1->2->null 给出 1->1->2->3 ...
- php实现图片以base64显示的方法达到效果
目前Data URI scheme支持的类型有: data:text/plain,文本数据data:text/html,HTML代码data:text/html;base64,base64编码的HTM ...
- Wireshark 基本使用方法
学习于: http://www.cnblogs.com/TankXiao/archive/2012/10/10/2711777.html
- kubernetes1.4新特性:增加新的节点健康状况类型DiskPressure
背景资料 在Kubernetes架构图中可以看到,节点(Node)是一个由管理节点委托运行任务的worker. 它能运行一个或多个Pods,节点(Node)提供了运行容器环境所需要的所有必要条件,在K ...
- [Offer收割]编程练习赛104
题目过于简单,没啥好说的,但是拿了个第一感觉很爽,记录一下 题目1 : 小Hi与魔法 排序,从1开始递增 #include <bits/stdc++.h> using namespace ...
- 第三十二讲:UML类图(下)
一个类能够看到另外一个类的属性和方法,那么这两个类是关联的.
- bzoj1412 狼和羊的故事
Description “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! O ...
- Linux终端常用命令(一)
基本操作 展示全部的环境变量 export 搜索可执行文件.源文件 whereis ls 在环境变量中搜索可执行文件,并打印完整路径 which ls 展示用户命令,系统调用.库函数等 whatis ...