CSP历年复赛题-P1096 [NOIP2007 普及组] Hanoi 双塔问题
原题链接:https://www.luogu.com.cn/problem/P1096
题意解读:汉诺双塔的移动次数,与经典汉诺塔的区间在于同一个尺寸盘子有两个。
解题思路:
可以直接用经典汉诺塔方法来计算,双塔的结果就最终乘以2即可。
首先想到的是递归,但是由于数据量n最大200,递归会超时,但是50%的样例应该没问题,先拿分!
50分代码:
#include <bits/stdc++.h>
using namespace std;
int ans;
void hanoi(int n)
{
if(n == 1)
{
ans++; //只剩一个盘子,移动到目标柱子
return;
}
hanoi(n-1); //移动前n-1个盘子都暂存柱子
ans++; //移动第n个到目标柱子
hanoi(n-1); //移动前n-1个到目标柱子
}
int main()
{
int n;
cin >> n;
hanoi(n);
cout << ans * 2; //双塔乘以2
return 0;
}
根据提示,考虑采用递推,直接借助上面递归代码运行出
n = 1,输出2
n = 2,输出6
n = 3,输出14
n = 4,输出30
n = 5,输出62
我们观察一下2,6,14,30,62,可以推出递推式f[n] = f[n-1] * 2 + 2,初始值f[1] = 2,最终结果是f[n]
由于n最大是200,2^200用long long也无法存储,需要高精度
先写出以下代码,再替换高精度
70分代码:
#include <bits/stdc++.h>
using namespace std;
long long f[205];
int main()
{
int n;
cin >> n;
f[1] = 2;
for(int i = 2; i <= n; i++)
{
f[i] = f[i-1] * 2 + 2;
}
cout << f[n];
return 0;
}
加上高精度,只需要加法即可!
100分代码:
#include <bits/stdc++.h>
using namespace std;
vector<int> f[205];
vector<int> g2(1, 2); //高精度的2
vector<int> add(vector<int> &a, vector<int> &b)
{
vector<int> res;
int t = 0;
int len = max(a.size(), b.size());
for(int i = 0; i < len; i++)
{
if(i < a.size()) t += a[i];
if(i < b.size()) t += b[i];
res.push_back(t % 10);
t /= 10;
}
if(t) res.push_back(t);
return res;
}
int main()
{
int n;
cin >> n;
f[1] = g2;
for(int i = 2; i <= n; i++)
{
vector<int> res = add(f[i-1], f[i-1]);
f[i] = add(res, g2);
}
for(int i = f[n].size() - 1; i >= 0; i--) cout << f[n][i];
return 0;
}
分类:
CSP-J复赛真题解析
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?