洛谷P1009 阶乘之和

T1173 阶乘和

题目传送门
首先,题目里说了高精度,那还想什么?
这里介绍一个有亿点点难懂的方法

上课!

第一步

首先,先建立一个结构体来模拟大整数类。结构体不仅可以包含成员变量,还能定义成员函数。
代码如下:

#define maxn 100
struct Bigint
{
    int len,a[maxn];//为了兼顾效率和复杂度,用 len 记录位数,a 记录每个数位
    Bigint(int x=0)//通过初始化,使得这个大整数能够表示整型 x,默认为 0
    {
		memset(a,0,sizeof(a));
		for(len=1;x;len++)
		{
			a[len]=x%10;
			x/=10;
		}
		len--;
	}
	int &operator[](int i)
	{
		return a[i];//重载 [],可以直接用 x[i] 表示 x.a[i],编写时间更加自然
	}
	void flatten(int L)//一口气处理 1 到 L范围内的进位并重置长度
	{
		len=L;
		for(int i=1;i<=len;i++)
		{
			a[i+1]+=a[i]/10;
			a[i]%=10;
		}
		for(;!a[len];)//同 while(len>1 && !a[len])
			len--;//重置长度为有效长度
	}
	void print()//输出
	{
		for(int i=max(len,1);i>=1;i--)
			printf("%d",a[i]);
	}
};

搞定!

第二步

阶乘之和,肯定要求和啊,那就需要一个大整数类求和函数。
如下:

Bigint operator+(Bigint a,Bigint b)//表示两个 Bigint 类型数相加,返回一个 Bigint 类型数
{
	Bigint c;
	int len=max(a.len,b.len);
	for(int i=1;i<=len;i++)
		c[i]+=a[i]+b[i];//计算
	c.flatten(len+1);//答案不超过 len+1 位,所以用 len+1 做一下 “展平 ”处理进位
	return c;
}

阶乘,那也需要求积,类似的,需要一个大整数类求积函数。
如下:

Bigint operator*(Bigint a,int b)//表示 Bigint 类型数与整型变量相乘,返回一个 Bigint 类型数
{
	Bigint c;
	int len=a.len;
	for(int i=1;i<=len;i++)
		c[i]=a[i]*b;//计算
	c.flatten(len+11);//答案不超过 len+1 位,所以用 len+1 做一下 “展平 ”处理进位
	return c;
}

第三步

前面千辛万苦封装结构体,就是为了后面能用的轻松。计算阶乘时,不需要每次循环从 \(1\) 乘到 \(n\),而是用变量,每次乘 \(i\) 并记录即可。
主函数如下:

int main()
{
	Bigint ans(0),fac(1);//分别用 0 和 1 初始化 ans 和 fac
	int m;
	cin>>m;
	for(int i=1;i<=m;i++)
	{
		fac=fac*i;//模拟题意
		ans=ans+fac;
	}
	ans.print();//输出
}

结束!

最后,贴一下 \(AC\) \(Code\)

#include<bits/stdc++.h>
#define maxn 100
using namespace std;
struct Bigint
{
    int len,a[maxn];
    Bigint(int x=0)
    {
		memset(a,0,sizeof(a));
		for(len=1;x;len++)
		{
			a[len]=x%10;
			x/=10;
		}
		len--;
	}
	int &operator[](int i)
	{
		return a[i];
	}
	void flatten(int L)
	{
		len=L;
		for(int i=1;i<=len;i++)
		{
			a[i+1]+=a[i]/10;
			a[i]%=10;
		}
		for(;!a[len];)
			len--;
	}
	void print()
	{
		for(int i=max(len,1);i>=1;i--)
			printf("%d",a[i]);
	}
};
Bigint operator+(Bigint a,Bigint b)
{
	Bigint c;
	int len=max(a.len,b.len);
	for(int i=1;i<=len;i++)
		c[i]+=a[i]+b[i];
	c.flatten(len+1);
	return c;
}
Bigint operator*(Bigint a,int b)
{
	Bigint c;
	int len=a.len;
	for(int i=1;i<=len;i++)
		c[i]=a[i]*b;
	c.flatten(len+11);
	return c;
}
int main()
{
	Bigint ans(0),fac(1);
	int m;
	cin>>m;
	for(int i=1;i<=m;i++)
	{
		fac=fac*i;
		ans=ans+fac;
	}
	ans.print();
}

好了,下课!

走前留个赞吧 QWQ
posted @ 2023-08-05 18:59  XLoffy  阅读(40)  评论(0编辑  收藏  举报