HDOJ-2175 汉诺塔IX

题目大意:基于汉诺塔原型,第一根柱子上有n个盘子,从上至下编号从1依次递增至n。在最佳移动方案中,第m次所移动的盘子的编号。

解题思路:模拟必然是会超时的。但根据汉诺塔的递归原理,容易发现,对于n阶汉诺塔,将第一个盘从A柱移动到B柱是一步,将前两个盘从A柱移动到B柱是3步,以此类推,将n个盘从A柱移动到B柱的步数是2^n-1步。而第m步必然在以上递推的值所划分出来的区间之中。查找到区间i后,可以发现,我们把问题缩小为求n-i阶汉诺塔的第m-(used[i]+1)步。同时,如果发现第m步正好是i阶汉诺塔移动后的下一步,那必然是移动i+1号盘子,若正好是i阶汉诺塔移动的步数,那就必然是1号盘子,这就是递归的边界了。

每一阶所需的步数可以用公式快速得出并预缓存,相对于模拟,这种区间查找,缩小范围的方法极大地降低了时间复杂度。

 1 #include <iostream>
 2 using namespace std;
 3 long long int cache[66];
 4 int flag=1;
 5 void find(long long int m)
 6 {
 7     int i;
 8     for(i=1;i<=65;i++)
 9     {
10         if(cache[i]==m)
11         {
12             flag=1;
13             return;
14         }
15         if(cache[i]<m&&m<cache[i+1])
16         {
17             if((cache[i]+1)==m)
18             {
19                 flag=i+1;
20                 return;
21             }
22             else
23             {
24                 find(m-(cache[i]+1));
25             }
26         }
27     }
28 }
29 int main() {
30     int i;
31     cache[1]=1;
32     for(i=2;i<=65;i++)
33     {
34         cache[i]=cache[i-1]*2+1;
35     }
36     long long int n,m;
37     while(cin>>n>>m)
38     {
39         if(n==0&&m==0)
40             break;
41         flag=1;
42         find(m);
43         cout<<flag<<endl;
44     }
45         return 0;
46 }
时间: 2024-10-11 09:11:49

HDOJ-2175 汉诺塔IX的相关文章

HDU 2175 汉诺塔IX (递推)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2175 1,2,...,n表示n个盘子.数字大盘子就大.n个盘子放在第1根柱子上.大盘不能放在小盘上. 在第1根柱子上的盘子是a[1],a[2],...,a[n]. a[1]=n,a[2]=n-1,...,a[n]=1.即a[1]是最下 面的盘子.把n个盘子移动到第3根柱子.每次只能移动1个盘子,且大盘不能放在小盘上. 问第m次移动的是那一个盘子. Input每行2个整数n (1 ≤ n ≤ 63)

hdu2175汉诺塔IX

汉诺塔IX Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 775    Accepted Submission(s): 462 Problem Description 1,2,...,n表示n个盘子.数字大盘子就大.n个盘子放在第1根柱子上.大盘不能放在小盘上. 在第1根柱子上的盘子是a[1],a[2],...,a[n]. a[1]=

[acm]HDOJ 2064 汉诺塔III

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=2064 汉诺塔变种,只能从中间专业,递归关系为:f(n)=3*f(n-1)+2. 1 //汉诺塔变种,只能从中间转移 2 //11485816 2014-08-19 08:44:47 Accepted 2064 0MS 368K 307 B G++ 空信高手 3 #include<iostream> 4 #include<cstdio> 5 using namespace std; 6

汉若塔系列续:汉诺塔VIII、汉诺塔IX、汉诺塔X。

汉诺塔VIII,在经典汉若塔问题上.问n个盘子的情况下,移动m次以后,是什么状态. (与第七代互为逆命题) 我的思路:本质还是dfs,可是用m的值来指引方向,每搜一层确定第i个盘子在哪个塔,o(n)的算法,看图说明: #include<iostream> #include<vector> using namespace std; char get[65]; //记录I号盘子在哪个塔 long long f[65]; //2^i次的值 void got() //预处理的f[i]; 注

Hdu 1207 汉诺塔II

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8433    Accepted Submission(s): 4162 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

HDU 1207 汉诺塔II (递推)

经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往上按大小顺序摞着64片黄金圆盘.上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一回只能移动一个圆盘.有预言说,这件事完成时宇宙会在一瞬间闪电式毁灭.也有人相信婆罗门至今仍在一刻不停地搬动着圆盘.恩,当然这个传说并不可信,如今汉诺塔更多的是作为一个玩具存在.Gardon

汉诺塔II(hdu1207)经典递推

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6070    Accepted Submission(s): 2966 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下

HDU1207 汉诺塔II(递推)

汉诺塔II Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往上按大小顺序摞着64片黄金圆盘.上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一回只能移动一个圆盘.有预言说,这件事完成时宇宙会在一瞬间闪电式毁灭.也有人相信婆罗门至今仍在一刻不停地搬动着圆盘.恩,当然这个传说并不可

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往