HANOI

HANOI

the easiest one

Hanoi双塔问题

题目大意:

用最少的次数,把那三个圆柱给移到指定的C柱上,然后把次数输出(要最少的)

找规律

首先来说一下等差序列:
一阶:形如1,3,5,7,9……
高级:二阶:1,4,9,16,25……

1+2+3+4+……n=n(n+1)/2
12+22+32+42+……+n2=n(n+1)(2n+1)/6
1 × \times × 2+2 × \times × 3+……+n × \times × (n+1)=1/3(2 × \times × 3 × \times × 4 -1 × \times × 2 × \times × 3)+……=1/3n(n+1)(n+2)

此题:首先,这道题的解题过程可以分成三部分:

一、将前2*(N-1)个盘子移到B柱;(不然你最后两个盘子移不出来);

二、将最后两个盘子移到C柱;

三、再将B柱上的2*(N-1)个盘子移到C柱;

然后,我们可以开一个数组F[N]表示将2*N个盘子从一个柱子移到另一个柱子所用的最少步数。

所以:f(n)=2^(a+1)-2

注意:一定要高精
代码:a=int(input()) print(2**(a+1)-2)Python

more difficult

给你一个数m,求第m步是编号为几的盘子从哪到哪(64<m<100)

void print(int n, char A, char B, char C) {
if (n == 0) return;
print(n - 1, A, C, B);
printf("%d %c %c", n, A, C);
print(n - 1, B, A, C);
}
调用print(n, ‘A’, ‘B’, ‘C’)
那你考虑
printK(int n, int k, char A, char B, char C)
表示输出第k步
那么考虑第k步是在
print(n - 1, A, C, B);
printf("%d %c %c", n, A, C);
print(n - 1, B, A, C);
这三行里哪一个
如果k <= 2(n-1) - 1
那么就是第一行里,递归调用
printK(n - 1, k, A, C, B);
如果k = 2(n-1)那么就正好在中间那一行,因此输出
printf("%d %c %c", n, A, C);
否则的话相当于先把k减去2^(n-1)然后往后面递归
也就是调用
printK(n - 1, k - (1 << (n - 1)), A, C, B);
那么相当于把k写成二进制
从第n-1位往右扫到第0位
如果扫到一个0,说明这一步是第一种情况,递归下去相当于swap(B, C)
如果扫到一个1,那么是第三种
这时候相当于swap(A,B)
如果这个1正好是二进制最后一个1,那就说明剩下的是一个2i
这时候print(i+1, A, C)

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n,ans=0;
unsigned long long m;
void dfs(int n,unsigned long long m,char a,char b,char c){
	unsigned long long k=1ull<<(n-1);
	if(m==k){
		printf("move %d from  %c to %c",n,a,c);
		return ;
	}
	else if(m<k)dfs(n-1,m,a,c,b);
	else if(m>k)dfs(n-1,m-k,b,a,c);
}
int main(){
	scanf("%d%u",&n,&m);
	
	dfs(n,m,'A','B','C');
	return 0;
}

四塔问题

再来看四塔问题。对于F(n),我们可以先把A中的j(0 ≤ j < n)个盘子移到B,需要F(j)次操作,然后在柱子ACD中,完成剩下的n-j个盘子操作——把A中n-j个盘子,利用C,移动到D,这等价于三塔问题,所以操作次数为H(n-j),再把B中的j个盘子移到D,操作F(j)次。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值