1028. Hanoi Tower Sequence
1028. Hanoi Tower Sequence
Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
Hanoi Tower is a famous game invented by the French mathematician Edourard Lucas in 1883. We are given a tower of n disks, initially stacked in decreasing size on one of three pegs. The objective is to transfer the entire tower to one of the other pegs, moving only one disk at a time and never moving a larger one onto a smaller.
The best way to tackle this problem is well known: We first transfer the n-1 smallest to a different peg (by recursion), then move the largest, and finally transfer the n-1 smallest back onto the largest. For example, Fig 1 shows the steps of moving 3 disks from peg 1 to peg 3.

Now we can get a sequence which consists of the red numbers of Fig 1: 1, 2, 1, 3, 1, 2, 1. The ith element of the sequence means the label of the disk that is moved in the ith step. When n = 4, we get a longer sequence: 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1. Obviously, the larger n is, the longer this sequence will be.
Given an integer p, your task is to find out the pth element of this sequence.
Input
The first line of the input file is T, the number of test cases.
Each test case contains one integer p (1<=p<10^100).
Output
Output the pth element of the sequence in a single line. See the sample for the output format.
Print a blank line between the test cases.
Sample Input
4
1
4
100
100000000000000
Sample Output
Case 1: 1 Case 2: 3 Case 3: 3 Case 4: 15
Problem Source
ZSUACM Team Member
// Problem#: 1028
// Submission#: 2346268
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include<iostream>
#include<cmath>
#include<string>
using namespace std; bool diff(string a,string b){
int lena=a.size();
int lenb=b.size();
if(lena<lenb)
return true;
else if(lena == lenb){
int i;
for(i=0;i<lena;i++){
if(a[i]<b[i]){
return true;
}
else if(a[i]==b[i]){
}
else{
return false;
}
}
}
else
return false;
return false;
}
string add(string a,string b){
string temp;
int lena=a.size();
int lenb=b.size();
int x,y;
x=lena;
y=lenb;
if(x>y){
temp='0'+a;
int i=0;
int lent=temp.size();
for(i=1;i<=lenb;i++){
temp[lent-i-1]=((temp[lent-i]-'0')+(b[lenb-i]-'0'))/10+temp[lent-i-1];
temp[lent-i]=((temp[lent-i]-'0')+(b[lenb-i]-'0'))%10+'0'; }
}
else{
temp='0'+b;
int lent=temp.size();
int i=0;
for(i=1;i<=lena;i++){
temp[lent-i-1]=((a[lena-i]-'0')+(temp[lent-i]-'0'))/10+temp[lent-i-1];
temp[lent-i]=((a[lena-i]-'0')+(temp[lent-i]-'0'))%10+'0'; }
}
int lent=temp.size();
int i=0;
while(temp[i]=='0'){
i++;
}
temp.erase(temp.begin(),temp.begin()+i);
return temp;
} string pluss(string a,string b){
string temp;
int lena=a.size();
int lenb=b.size();
int x=lena,y=lenb;
int key;
for(key=1;key<=y;key++){
if(a[lena-key]>=b[lenb-key]){
temp=(char)(a[lena-key]-b[lenb-key]+'0')+temp;
}
else if(a[lena-key-1]!='0'){
a[lena-key-1]=a[lena-key-1]-1;
temp=(char)(a[lena-key]-b[lenb-key]+'0'+10)+temp;
}
else{
int i=1;
while(a[lena-key-i]=='0'){
i++;
}
a[lena-key-i]=a[lena-key-i]-1;
i--;
while(i>=1){
a[lena-key-i]='9';
i--;
}
temp=(char)(a[lena-key]-b[lenb-key]+'0'+10)+temp;
}
}
int lent=temp.size();
int i=0;
while(temp[i]=='0'){
i++;
}
temp.erase(temp.begin(),temp.begin()+i);
return temp;
} int getCase(string p){
int i=0;
string temp;
temp=temp+'1';
string front;
while(diff(temp,p)){
front=temp;
temp=add(temp,temp);
i++;
}
if(temp==p){
return i+1;
}
else{
p=pluss(p,front);
return getCase(p);
}
} int main(){
int n;
cin>>n;
int i=0;
while(n--){
string p;
i++;
cin>>p;
if(n==0){
cout<<"Case "<<i<<": "<<getCase(p)<<endl;
}
else{
cout<<"Case "<<i<<": "<<getCase(p)<<endl<<endl;
}
}
return 0;
}
首先是要找规律,然后是大精度加减法以及比较大小的问题,大精度的那些函数是用string实现的。
至于规律,我们可以简单的写下钱16次操作,我们会发现,当操作次数为2的(0,1,2,3....)次方的时候,对应操作的disk序号一定是第一次出现(1,2,3,4...),而且为操作次数加1,另外你会发现操作数为2的(0,1,2,3....)次方的时候下一位一定从disk1开始重复前面的所有步。
所以我们可以找到离操作数最近的那个2的幂,然后把操作数减去2的幂得到的值赋值给操作数,再用递归的方法求出答案。方法仅供参考。
1028. Hanoi Tower Sequence的更多相关文章
- HDU1329 Hanoi Tower Troubles Again!——S.B.S.
Hanoi Tower Troubles Again! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- ZOJ-1239 Hanoi Tower Troubles Again!
链接:ZOJ1239 Hanoi Tower Troubles Again! Description People stopped moving discs from peg to peg after ...
- Codeforces Gym 100114 A. Hanoi tower 找规律
A. Hanoi tower Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descript ...
- 汉诺塔 Hanoi Tower
电影<猩球崛起>刚开始的时候,年轻的Caesar在玩一种很有意思的游戏,就是汉诺塔...... 汉诺塔源自一个古老的印度传说:在世界的中心贝拿勒斯的圣庙里,一块黄铜板上插着三支宝石针.印度 ...
- HDU 1329 Hanoi Tower Troubles Again!(乱搞)
Hanoi Tower Troubles Again! Problem Description People stopped moving discs from peg to peg after th ...
- 3-6-汉诺塔(Hanoi Tower)问题-栈和队列-第3章-《数据结构》课本源码-严蔚敏吴伟民版
课本源码部分 第3章 栈和队列 - 汉诺塔(Hanoi Tower)问题 ——<数据结构>-严蔚敏.吴伟民版 源码使用说明 链接☛☛☛ <数据结构-C语言版> ...
- Python学习札记(十四) Function4 递归函数 & Hanoi Tower
reference:递归函数 Note 1.在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. eg.计算阶乘: #!/usr/bin/env python3 def ...
- zoj 2954 Hanoi Tower
Hanoi Tower Time Limit: 2 Seconds Memory Limit: 65536 KB You all must know the puzzle named "Th ...
- 10276 - Hanoi Tower Troubles Again!(思维,模拟)
People stopped moving discs from peg to peg after they know the number of steps needed to complete t ...
随机推荐
- Oracle VM VirtualBox做好虚拟硬盘后,如何进一步修改虚拟硬盘的大小
以管理员身份打开, 命令提示符窗口,然后利用命令cd进入Oracle VM VirtualBox安装目录,如下图: 我进入了Oracle VM VirtualBox安装目录:D:\Program Fi ...
- poj1417(带权并查集+背包DP+路径回溯)
题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说 ...
- FileUpload控件实现单按钮图片自动上传并带预览显示
FileUpload控件实现单按钮图片自动上传并带预览显示 1.实现原理: FileUpload控件默认不支持服务端的ONCHANGE事件,此时用一种变通的方法借用客户端的onchange事件,调 ...
- python之socket运用2
今天实现在客户端和服务端之间进行持续的通信 客户端代码 import socket ip_port = ("127.0.0.1",3000) sk = socket.socket( ...
- 苹果 重置APPID密保问题及更新开发者协议
[链接]重置AppleID密保问题 https://www.jianshu.com/p/37e7f2852eda [链接]苹果开发者计划许可协议更新:持续更新 https://www.jianshu. ...
- Collections.shuffle()源码分析
Java.util.Collections类下有一个静态的shuffle()方法,如下: 1)static void shuffle(List<?> list) 使用默认随机源对列表进行 ...
- ROS学习笔记二(创建ROS软件包)
catkin软件包的组成 一个软件包必须满足如下条件才能被称之为catkin软件包: 必须包含一个catkin编译文件package.xml(manifests文件),此文件包含了描述该软件包的重要信 ...
- Struts2的拦截器技术
1. 拦截器的概述 * 拦截器就是AOP(Aspect-Oriented Programming,面向切面)的一种实现.(AOP是指用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作 ...
- Spring框架中Bean管理的常用注解
1. @Component:组件.(作用在类上)可以作用在任何一个类上 2. Spring中提供@Component的三个衍生注解:(功能目前来讲是一致的) * @Controller -- 作用在W ...
- Halcon一维码和二维码的解码步骤和技巧——第11讲
针对Halcon中一维码和二维码的解码,我分别写了两篇文章,参见: <Halcon的一维条码解码步骤和解码技巧>:https://www.cnblogs.com/xh6300/p/1048 ...