洛谷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();
}