汉诺塔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]; 注意点:用1<<i会爆int。
{
f[1]=2;
for(int i=2;i<65;i++)
f[i]=f[i-1]*2;
}
void dfs(char fl,char fr,char now,int lev,long long x) //同汉若塔第七代理,LVE是层数,x是目前的值
{
get[lev]=now;
if(lev==1)return; //出口
char temp;
if(fl=='A'&&fr=='B'||fl=='B'&&fr=='A')temp='C';
else if(fl=='A'&&fr=='C'||fl=='C'&&fr=='A')temp='B';
else temp='A';
lev--;
long long tx=(f[lev]-1)/2;
if(x<=tx) //小于它的
{
if(now==fl) //左边的下来
dfs(fl,temp,fl,lev,x);
else
dfs(temp,fr,temp,lev,x);
}
else
{
if(now==fl)
dfs(fl,temp,temp,lev,x-tx-1); //减一,那一步是最下面的塔的移动
else
dfs(temp,fr,fr,lev,x-tx-1);
}
}
int main()
{
got();
int T;
cin>>T;
while(T--)
{
long long n,m;
cin>>n>>m;
if(m<=(f[n]-1)/2)
dfs('A','C','A',n,m);
else
dfs('A','C','C',n,m-(f[n]-1)/2);
vector<int>a,b,c;
for(int i=n;i>=1;i--)
{
if(get[i]=='A')a.push_back(i);
else if(get[i]=='B')b.push_back(i);
else c.push_back(i);
}
cout<<a.size();
for(int i=0;i<a.size();i++)
cout<<" "<<a[i];
cout<<endl;
cout<<b.size();
for(int i=0;i<b.size();i++)
cout<<" "<<b[i];
cout<<endl;
cout<<c.size();
for(int i=0;i<c.size();i++)
cout<<" "<<c[i];
cout<<endl;
}
return 0;
}

汉若塔IX hdu2175,经典汉若塔问题上问第M次移动的是几号盘。

思路:同理,第n个盘之前,必先移动前n-1个,再移动第n号,再移动前n-1个,依次。所以二分法查找,在“中间”那个移动的酒在那一个盘了。

#include<iostream>
using namespace std;
long long f[65]; //2^i次的值
void got() //预处理的f[i]; 注意点:用1<<i会爆int。
{
f[0]=1;f[1]=2;
for(int i=2;i<65;i++)
f[i]=f[i-1]*2;
}
int main()
{
got();
long long n,m;
while(cin>>n>>m&&(n||m))
{
while(m!=f[n-1])
{
if(m<=f[n-1]-1)
;
else
m=m-f[n-1];
n--;
}
cout<<n<<endl;
}
return 0;
}

汉若塔X  hdu2511  求第m次移动是把几号盘从哪个塔到哪个塔移动。第九代的扩展。

思路:做到这里,每步的移动已经一清二楚了,还是那颗树,“左中右”遍历序列便是所有状态。由于一共就6种可能移动法。每次移动后知道下一步的移动。

依旧采用二分寻根法,详见代码:

#include<iostream>
#include<string>
using namespace std;
long long f[65]; //2^i次的值
void got() //预处理的f[i]; 注意点:用1<<i会爆int。
{
f[0]=1;f[1]=2;
for(int i=2;i<65;i++)
f[i]=f[i-1]*2;
}
string getnext(string s,int id) //状态转移
{
if(s=="AC")
{
if(id==0)return "AB";
else return "BC";
}
else if(s=="AB")
{
if(id==0)return "AC";
else return "CB";
}
else if(s=="CB")
{
if(id==0)return "CA";
else return "AB";
}
else if(s=="CA")
{
if(id==0)return "CB";
else return "BA";
}
else if(s=="BA")
{
if(id==0)return "BC";
else return "CA";
}
else if(s=="BC")
{
if(id==0)return "BA";
else return "AC";
}
}
int main()
{
got();
int T;
cin>>T;
long long n,m;
while(T--)
{
cin>>n>>m;
string s="AC";
while(m!=f[n-1])
{
if(m<=f[n-1]-1)
{
s=getnext(s,0);
}
else
{
s=getnext(s,1);
m=m-f[n-1];
}
n--;
}
if(s=="AB")
cout<<n<<" 1 2"<<endl;
if(s=="BA")
cout<<n<<" 2 1"<<endl;
if(s=="AC")
cout<<n<<" 1 3"<<endl;
if(s=="CA")
cout<<n<<" 3 1"<<endl;
if(s=="BC")
cout<<n<<" 2 3"<<endl;
if(s=="CB")
cout<<n<<" 3 2"<<endl;
}
return 0;
}

汉若塔系列续:汉诺塔VIII、汉诺塔IX、汉诺塔X。的更多相关文章

  1. HDU汉诺塔系列

    这几天刷了杭电的汉诺塔一套,来写写题解. HDU1207 汉诺塔II HDU1995 汉诺塔V HDU1996 汉诺塔VI HDU1997 汉诺塔VII HDU2064 汉诺塔III HDU2077  ...

  2. HBase之CF持久化系列(续3——完结篇)

    相信大家在看了该系列的前两篇文章就已经对其中的持久化有比较深入的了解.相对而言,本节内容只是对前两节的一个巩固.与持久化相对应的是打开文件并将其内容读入到内存变量中.而在本节,我就来介绍这一点. 本节 ...

  3. HBase之CF持久化系列(续2)

    正如上篇博文所说,在本节我将为大家带来StoreFlusher.finalizeWriter..如果大家没有看过我的上篇博文<HBase之CF持久化系列(续1)>,那我希望大家还是回去看一 ...

  4. 汉诺塔系列问题: 汉诺塔II、汉诺塔III、汉诺塔IV、汉诺塔V、汉诺塔VI

    汉诺塔 汉诺塔II hdu1207: 先说汉若塔I(经典汉若塔问题),有三塔.A塔从小到大从上至下放有N个盘子.如今要搬到目标C上. 规则小的必需放在大的上面,每次搬一个.求最小步数. 这个问题简单, ...

  5. HDU 汉诺塔系列

    做了这一系列题,表示对汉诺塔与这一系列递推理解加深了 经典汉诺塔:1,2,...,n表示n个盘子,数字大盘子就大,n个盘子放在第1根柱子上,按照从上到下 从小到大的顺序排放,过程中每次大盘都不能放在小 ...

  6. 文本编辑器激活系列(二):UltraEdit安装、激活、汉化教程

    如您激活出现问题,请点击这里加入:软件激活问题解决群 前言 推荐几款文本编辑器: Sublime:内嵌python解释器.大量插件 EditPlus:语法着色.内嵌浏览器 Notepad++:所见即所 ...

  7. 文本编辑器激活系列(一):Sublime 安装、激活、汉化教程

    如您激活出现问题,请点击这里加入:软件激活问题解决群 前言 推荐几款文本编辑器: Sublime:内嵌python解释器.大量插件 EditPlus:语法着色.内嵌浏览器 Notepad++:所见即所 ...

  8. HBase之CF持久化系列(续1)

    这一节本来打算讲解HRegion的初始化过程中一些比较复杂的流程.不过,考虑前面的博文做的铺垫并不够,因此,在这一节,我还是特意来介绍HBase的CF持久化.关于这个话题的整体流程性分析在博文< ...

  9. 算法笔记_013:汉诺塔问题(Java递归法和非递归法)

    目录 1 问题描述 2 解决方案  2.1 递归法 2.2 非递归法 1 问题描述 Simulate the movement of the Towers of Hanoi Puzzle; Bonus ...

随机推荐

  1. Python基础篇 -- 字符串

    字符串 字符串是不可变的对象,任何操作对原字符串是不会有任何影响的. 索引和切片 索引 . 索引就是下标, 下标从 0 开始, 使用[] 来获取数据 s1 = "0123456" ...

  2. HTML5开发手机应用--viewport的作用--20150216

    在用HTML5开发手机应用或手机网页时,<head>部分总会有如下一段代码,这段代码到底什么意思呢.在网上,大家会得到很多答案.我从网上搜集了部分介绍,整理一下,以留备用. <met ...

  3. 转: opencv4.0.0 +opencv_contrib在vs2015中编译

    https://blog.csdn.net/baidu_40691432/article/details/84957737

  4. 【OS_Linux】Linux下软件的安装与卸载

    1.Linux中软件安装包的分类 1) 一类是可执行的软件包,无需编译直接安装.在Windows中所有的软件包都是这种类型.安装完这个程序后,你就可以使用,但你看不到源程序.而且下载时要注意这个软件是 ...

  5. (62)zabbix客户端自动注册

    1. 概述 上一篇内容<zabbix自动发现配置>,大概内容是zabbix server去扫描一个网段,把在线的主机添加到Host列表中. 我们本篇内容与上篇相反,这次是Active ag ...

  6. Linux服务器的弱口令检测及端口扫描

    一.弱口令检测--John the Ripper John the Ripper工具可以帮助我们扫描出系统中密码安全性较低的用户,并将扫描后的结果显示出来. 1.安装John the Ripper: ...

  7. centos 装 jdk

    1.源码包准备: 首先到官网下载jdk,http://www.oracle.com/technetwork/java/javase/downloads/jdk7- downloads-1880260. ...

  8. Java包(package)详解

    java包的作用是为了区别类名的命名空间 1.把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用.. 2.如同文件夹一样,包也采用了树形目录的存储方式.同一个包中的类名字是不同的,不同的包 ...

  9. 【LeetCode】Two Sum(两数之和)

    这道题是LeetCode里的第1道题. 题目描述: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会 ...

  10. 贴一下我写过的c++程序代码

    5258 #include <iostream>#include <iomanip>#include <cmath>using namespace std;clas ...