凭借感觉搭的高精(慎用形如“++i”的计算符)
查看原帖
凭借感觉搭的高精(慎用形如“++i”的计算符)
86003
ChristopherL楼主2020/10/2 00:18

时隔一年多回洛谷,挑战一下当年写得头大的高精度题。特别的感想,慎用“++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; 
	}
    ```
2020/10/2 00:18
加载中...