时隔一年多回洛谷,挑战一下当年写得头大的高精度题。特别的感想,慎用“++i”这样的计算符: 在本地dev中
int cnt=1;
a[cnt]=b[++cnt]+c[cnt];
printf("cnt=%d" ,cnt);
等价于
a[1]=b[2]+c[2];
cnt=2;
但在洛谷网上IDE中却等价于
a[1]=b[2]+c[1];
cnt=2;
鬼知道这个bug我找了多久,最后上在线IDE查出了这毛病。 步入正题: 本题的母题是经典递归问题:汉诺塔(有兴趣的同学可以去《具体数学——计算机科学基础》里找到这道题的详解)从开放式(f[n]=2f[n-1]+1)不难通过我们小学二年级就学过的数列知识求出其封闭式(f[n]=2^n-1),但是本题有个变形,即每种盘子有两个,所以answer[n]=2f[n]。其中f[n]依旧满足上述封闭式。 第二个需要注意的地方是此题的数据大小,不同寻常啊,竟然有200位。long long 显然是不行的。所以考虑使用高精度。 高精度的原理很简单,就是用数组来模拟算术计算,我早已忘记了板子,就凭借自己的理解一步一步搭了个板子,勉强把这道题破了。好吧,上代码。
#include<cmath>
#include<iostream>
#include<cstdio>
#define SIZE 1000
using namespace std;
int n[SIZE],J[SIZE]; //n存放高精数据 ,J存放进位
int N,cnt;
void Jinwei()
{
int x;
for(int i=1;i<=cnt;i++)
{
x=n[i]+J[i];
if(x>9) J[i+1]+=x/10;
n[i]=x%10;
}
if(J[cnt+1]) n[++cnt]=J[cnt];
}
void Minus2()
{
if(n[1]>=2)
{
n[1]-=2;
return;
}
int i=2;
for(i;i;i++) if(n[i]) break;
for(int j=2;j<i;j++) n[j]=9;
n[i]-=1;
n[1]+=8;
return;
}
void Calculate()
{
for(int j=1;j<=N+1;j++)
{
for(int q=1;q<=cnt;q++) J[q]=0;
int nct=cnt;
for(int i=1;i<=nct;i++)
{
n[i]<<=1;
if(n[i]>9)
{
J[i+1]=n[i]/10;
n[i]%=10;
}
}
Jinwei();
}
}
int main()
{
cin >> N;
n[++cnt]=1;
Calculate();
Minus2();
for(int i=cnt;i>=1;i--) cout << n[i];
return 0;
}
```