洛谷 P1760 通天之汉诺塔

题目背景

直达通天路·小A历险记第四篇

题目描述

在你的帮助下,小 A 成功收集到了宝贵的数据,他终于来到了传说中连接通天路的通天山。但是这距离通天路仍然有一段距离,但是小 A 突然发现他没有地图!!!但是幸运的是,他在山脚下发现了一个宝箱。根据经验判断(小 A 有经验吗?),地图应该就在其中!

在宝箱上,有三根柱子以及在一根柱子上的 n n n 个圆盘。小 A 在经过很长时间判断后,觉得这就是 hanoi 塔!(这都要琢磨)。但是移动是需要时间的,所以小 A 必须要通过制造延寿药水来完成这项任务。现在,他请你告诉他需要多少步完成,以便他造足够的延寿药水。

输入格式

一个数 n n n,表示有 n n n 个圆盘。

输出格式

一个数 s s s,表示需要 s s s 步。

样例 #1

样例输入 #1

31

样例输出 #1

2147483647

样例 #2

样例输入 #2

15

样例输出 #2

32767

提示

数据范围及约定

对于所有数据, n ≤ 15000 n \le 15000 n15000

题目讲解

对于这个题目我们可以想到一个非常暴力的思路:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int n=0,x=1;char c;
	for(c=getchar();c<'0'||c>'9';c=getchar())
		if(c=='-')x=-1;else x=1;
	for(;c>='0'&&c<='9';c=getchar())
		n=(n<<3)+(n<<1)-'0'+c;
	return x*n;
}
int dfs(int x)
{
	if(x==1) return 1;
	return dfs(x-1)*2+1;
}
int main()
{
	cout<<dfs(read());
	
	return 0;
}

对于这个暴力思路只能过40分的数据所以我们要想别的办法:

在这里插入图片描述
这样我们就可以直接写出代码:

code:

#include<bits/stdc++.h>
#define int long long
using namespace std;
vector<int> mul(vector<int> a,vector<int> b)
{
	vector<int> c(a.size()+b.size()+1);
	for(int i=0;i<a.size();++i)
	{
        for(int j=0;j<b.size();++j)
		{
			c[i+j]+=a[i]*b[j];
            c[i+j+1]+=c[i+j]/10;
            c[i+j]%=10;
        }
	}
	while(c.size()>1 && c.back()==0) c.pop_back();
	return c;
}
vector<int> qpow(vector<int> a,int b)//高精度快速幂
{
	vector<int> res;
	res.push_back(1);
	while(b)
	{
    	if(b&1)
		{
			res=mul(res,a);
		}
    	a=mul(a,a);
    	b>>=1;
	}
 	return res;
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int n;
	cin>>n;
	auto ans=qpow({2},n);
	ans[0]-=1;
	reverse(ans.begin(),ans.end());
	for(auto it:ans)
	{
		cout<<it;
	}

	return 0;
}
注意事项:本题不用快速幂也能过,蛋用快速幂可以进行优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值