当前位置:网站首页>信息学奥赛一本通 1941:【07NOIP普及组】Hanoi双塔问题 | 洛谷 P1096 [NOIP2007 普及组] Hanoi 双塔问题
信息学奥赛一本通 1941:【07NOIP普及组】Hanoi双塔问题 | 洛谷 P1096 [NOIP2007 普及组] Hanoi 双塔问题
2022-07-31 21:33:00 【君义_noip】
【题目链接】
ybt 1941:【07NOIP普及组】Hanoi双塔问题
洛谷 P1096 [NOIP2007 普及组] Hanoi 双塔问题
【题目考点】
1. 递推/递归
2. 高精度
【解题思路】
该问题为汉诺塔问题的变种。可以用递推或递归的方法完成。
解法1:递推
- 递推状态:记
a[i]
为将2*i个圆盘从A柱移动到C柱的圆盘移动次数。 - 初始状态:
a[1] = 2
。 - 递推关系:要想将2*i个圆盘从A柱移动到C柱,需要先把2*(i-1)个圆盘从A柱移动到B柱,需要移动
a[i-1]
次。而后将剩下的2个圆盘从A柱移动到C柱,移动2次。最后把B柱的2*(i-1)个圆盘移动到C柱,需要移动a[i-1]
次。所以a[i] = 2*a[i-1] + 2
假设所有变量都是低精度数字,写出代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, a[205];
cin >> n;
a[1] = 2;
for(int i = 2; i <= n; ++i)
a[i] = 2 * a[i-1] + 2;
cout << a[n];
return 0;
}
观察递推公式,可知 a i > 2 a i − 1 > 2 2 a i − 2 > . . . > 2 i − 1 a 1 = 2 i a_i > 2a_{i-1} > 2^2a_{i-2}>...>2^{i-1}a_1=2^i ai>2ai−1>22ai−2>...>2i−1a1=2i
题目中n最大为200,那么 a n > 2 n = 2 200 a_n>2^n=2^{200} an>2n=2200,求这个数字的位数: ⌊ l o g 10 2 200 ⌋ + 1 ≈ 62 \lfloor log_{10}2^{200}\rfloor +1\approx 62 ⌊log102200⌋+1≈62,这一定是个基本变量类型无法表示的数字,需要使用高精度数字。
观察低精度代码中,a应该从整型数组变为高精度数字的数组,2*a[i-1]+2
中,乘法是高精乘低精的运算,加法是高精加低精的运算。
可以用整型数组表示高精度数字,也可以把整型数组放在结构体中,构建高精度数字类型。也可以构建高精度数字类。
解法2:迭代:
也可以把上述递推代码变递推为迭代,而后将该低精度代码变为高精度。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, f;
cin >> n;
f = 2;
for(int i = 2; i <= n; ++i)
f = 2 * f + 2;
cout << f;
return 0;
}
解法2:递归
低精代码为
#include <bits/stdc++.h>
using namespace std;
int solve(int i)
{
if(i == 1)
return 2;
return 2 * solve(i - 1) + 2;
}
int main()
{
int n;
cin >> n;
cout << solve(n);
return 0;
}
把该代码改为高精度代码即可。
【题解代码】
解法1:递推 整型数组表示高精度数字
#include<bits/stdc++.h>
using namespace std;
#define N 105
void setLen(int a[], int i)
{
while(a[i] == 0 && i > 1)
i--;
a[0] = i;
}
void Multiply(int a[], int b, int r[])//高精乘低精 r = a * b
{
int c = 0, i;
for(i = 1; i <= a[0]; ++i)
{
r[i] = a[i] * b + c;
c = r[i] / 10;
r[i] %= 10;
}
while(c > 0)
{
r[i] = c % 10;
c /= 10;
i++;
}
setLen(r, i);
}
void Add(int a[], int b)//高精加低精 a += b
{
int c = b, i = 1;
while(c > 0)
{
a[i] += c;
c = a[i] / 10;
a[i] %= 10;
i++;
}
if(i > a[0])
setLen(a, i);
}
void showNum(int a[])
{
for(int i = a[0]; i >= 1; --i)
cout << a[i];
}
int main()
{
int n, a[205][N] = {
};//a[i]:2*i层汉诺塔从A移动到C的步数
cin >> n;
a[1][0] = 1, a[1][1] = 2;//a[1] = 2;
for(int i = 2; i <= n; ++i)
{
Multiply(a[i-1], 2, a[i]);//a[i] = 2*a[i-1];
Add(a[i], 2);//a[i] += 2
}
showNum(a[n]);
return 0;
}
解法2:迭代 结构体表示高精度数字
#include<bits/stdc++.h>
using namespace std;
#define N 105
struct HPN
{
int a[N] = {
};
};
void setLen(int a[], int i)
{
while(a[i] == 0 && i > 1)
i--;
a[0] = i;
}
void Multiply(HPN &a, int b)//高精乘低精 a *= b
{
int c = 0, i;
for(i = 1; i <= a.a[0]; ++i)
{
a.a[i] = a.a[i] * b + c;
c = a.a[i] / 10;
a.a[i] %= 10;
}
while(c > 0)
{
a.a[i] = c % 10;
c /= 10;
i++;
}
setLen(a.a, i);
}
void Add(HPN &a, int b)//高精加低精 a += b
{
int c = b, i = 1;
while(c > 0)
{
a.a[i] += c;
c = a.a[i] / 10;
a.a[i] %= 10;
i++;
}
if(i > a.a[0])
setLen(a.a, i);
}
void showNum(HPN a)
{
for(int i = a.a[0]; i >= 1; --i)
cout << a.a[i];
}
int main()
{
int n;
cin >> n;
HPN f;
f.a[0] = 1, f.a[1] = 2;//f = 2;
for(int i = 2; i <= n; ++i)
{
Multiply(f, 2);//f *= 2
Add(f, 2);//f += 2
}
showNum(f);
return 0;
}
解法3:递归 高精度数字类
#include<bits/stdc++.h>
using namespace std;
#define N 105
struct HPN
{
int a[N];
HPN()
{
memset(a, 0, sizeof(a));
}
HPN(string s)
{
a[0] = s.length();
for(int i = 1; i <= a[0]; ++i)
a[i] = s[a[0] - i] - '0';
}
int& operator [] (int i)
{
return a[i];
}
void setLen(int i)
{
while(a[i] == 0 && i > 1)
i--;
a[0] = i;
}
HPN operator * (int b)//a *= b
{
HPN r;
int c = 0, i;
for(i = 1; i <= a[0]; ++i)
{
r[i] = a[i] * b + c;
c = r[i] / 10;
r[i] %= 10;
}
while(c > 0)
{
r[i] = c % 10;
c /= 10;
i++;
}
r.setLen(i);
return r;
}
HPN operator + (int b)
{
HPN r = *this;
int c = b, i = 1;
while(c > 0)
{
r[i] += c;
c = r[i] / 10;
r[i] %= 10;
i++;
}
if(i > r[0])
r.setLen(i);
return r;
}
void show()
{
for(int i = a[0]; i >= 1; --i)
cout << a[i];
}
};
HPN solve(int i)
{
if(i == 1)
return HPN("2");
return solve(i - 1) * 2 + 2;//高精乘低精 高精加低精
}
int main()
{
int n;
cin >> n;
HPN r = solve(n);
r.show();
return 0;
}
边栏推荐
- 手把手教你学会部署Nestjs项目
- focus on!Haitai Fangyuan joins the "Personal Information Protection Self-discipline Convention"
- GAC Honda Safety Experience Camp: "Danger" is the best teacher
- Unity 之 音频类型和编码格式介绍
- renderjs usage in uni-app
- 【AcWing】The 62nd Weekly Match 【2022.07.30】
- 微信小程序的路由拦截
- "The core concept of" image classification and target detection in the positive and negative samples and understanding architecture
- 【AcWing】The 62nd Weekly Match 【2022.07.30】
- Linux environment redis cluster to build "recommended collection"
猜你喜欢
Getting Started with Tkinter
[Code Hoof Set Novice Village 600 Questions] Merge two numbers without passing a character array
[PIMF] OpenHarmony Thesis Club - Inventory of the open source Hongmeng tripartite library [3]
Daily practice——Randomly generate an integer between 1-100 and see how many times you can guess.Requirements: The number of guesses cannot exceed 7 times, and after each guess, it will prompt "bigger"
基于STM32 环形队列来实现串口接收数据
1161. 最大层内元素和 : 层序遍历运用题
如何才能真正的提高自己,成为一名出色的架构师?
Redis Overview: Talk to the interviewer all night long about Redis caching, persistence, elimination mechanism, sentinel, and the underlying principles of clusters!...
OSPFv3的基本配置
Teach you how to deploy Nestjs projects
随机推荐
1161. 最大层内元素和 : 层序遍历运用题
Linux环境redis集群搭建「建议收藏」
Poker Game in C# -- Introduction and Code Implementation of Blackjack Rules
NVIDIA已经开始测试AD106和AD107 GPU核心的显卡产品
全网一触即发,自媒体人的内容分发全能助手——融媒宝
leetcode:6135. 图中的最长环【内向基环树 + 最长环板子 + 时间戳】
第七章
Qualcomm cDSP simple programming example (to query Qualcomm cDSP usage, signature), RK3588 npu usage query
【愚公系列】2022年07月 Go教学课程 023-Go容器之列表
[PIMF] OpenHarmony Thesis Club - Inventory of the open source Hongmeng tripartite library [3]
ThreadLocal
ResNet的基础:残差块的原理
Flink_CDC construction and simple use
matplotlib ax bar color Set the color, transparency, label legend of the ax bar
程序员如何学习开源项目,这篇文章告诉你
Financial profitability and solvency indicators
npm 更改为淘宝镜像的方法[通俗易懂]
PCB stackup design
Go mode tidy reports an error go warning “all” matched no packages
Chapter Six