欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

P1009 阶乘之和

程序员文章站 2022-07-15 14:39:41
...

P1009 阶乘之和
1.为什么要用到高精度?
高精度算法:有时有的数会太大,甚至超过long long的范围
(2^63−1 ≈ 9× 10^18)
此时需要用字符串(string型或char型数组)来存储数字,运算时需要特殊的算法进行运算,称为高精度算法。高精度算法本质上是模拟数字的运算。

2.需要的高精度算法可以分解为加法,乘法((用到加法)),阶乘((用到乘法)),阶乘求和(用到阶乘与加法)。具体如下:

#include
#include

using namespace std;

int num; //输入的数
string ans; //输出的数

//高精度加法
string ADD(string a, string b)
{
string result; //结果

//将较大的数赋值给a,较小的数赋值给b
if(b.length() > a.length())
{
	string temp = a;
	a = b;
	b = temp;
}
int a_len = a.length();
int b_len = b.length();
//b补足零,方便计算
for(int i = 0; i < a_len - b_len; i++)
{
	b = '0' + b;
}

int num;        //本位
int up = 0;     //进位
//模拟加法
for(int i = a_len - 1; i >= 0; i--)
{
	int num = (a[i] - '0') + (b[i] - '0') + up;
	up = num / 10;
	num %= 10;
	result = (char)(num + '0') + result;
}
//若仍有进位,加上进位
if(up)
{
	result = (char)(up + '0') + result;
}

return result;

}

//高精度乘法
string MUL(string a, string b)
{
string result; //结果
int a_len = a.length();
int b_len = b.length();
int num; //本位
int up = 0; //进位
//模拟乘法
for(int i = a_len - 1; i >= 0; i–)
{
string temp;
for(int j = b_len - 1; j >= 0; j–)
{
num = (a[i] - ‘0’) * (b[j] - ‘0’) + up;
up = num / 10;
num %= 10;
temp = (char)(num + ‘0’) + temp;
}
//若仍有进位,加上进位,记得清零
if(up)
{
temp = (char)(up + ‘0’) + temp;
up = 0;
}
//乘以每位的权重10^k
for(int k = 0; k < (a_len - 1) - i; k++)
{
temp += ‘0’;
}
result = ADD(result, temp);
}

return result;

}

//高精度阶乘
string FAC(int n)
{
string result = “1”;

for(int i = 1; i <= n; i++)
{
	//数字转化为字符串
	string a;
	int temp = i;
	while(temp)
	{
		a = (char)(temp % 10 + '0') + a;
		temp /= 10;
	}
	result = MUL(result, a);
}

return result;

}

int main(void)
{
cin >> num;

for(int i = 1; i <= num; i++)
{
	ans = ADD(ans, FAC(i));
}

cout << ans;

return 0;

}

参考:
https://blog.csdn.net/justidle/article/details/104424134?utm_source=app&tdsourcetag=s_pcqq_aiomsg

P1009 阶乘之和

补一个解法:
#include <bits/stdc++.h>
using namespace std;
int a[10000],k=1,n;
int main()
{
cin>>n;
for(int i=n;i>=1;i–)
{
a[1]++;
for(int j=1;j<=a[0];j++)
{
a[j+1]+=a[j]/10;
a[j]%=10;
}
if(a[a[0]+1]>0)
{
a[0]++;
}
for(int j=1;j<=a[0];j++)
{
a[j]*=i;
}
for(int j=1;j<=a[0];j++)
{
a[j+1]+=a[j]/10;
a[j]%=10;
}
int x=a[0]+1;
if(a[x]>0)
{
while(a[x]>10)
{
a[x+1]=a[x]/10;
a[x]%=10;
x++;
}
a[0]=x;
}
}
for(int i=a[0];i>=1;i–)
{
cout<<a[i];
}

}

这个最精简:
#include
#include
using namespace std;
int n,a[101]={0},s[101]={0};
void change(int x)
{
int g=0;
for(int i=100;i>=0;i–)
{
a[i]=a[i]*x+g;
g=a[i]/10;
a[i]=a[i]%10;
}
}
void qh()
{
int g=0;
for(int i=100;i>=0;i–)
{
s[i]=s[i]+a[i]+g;
g=s[i]/10;
s[i]=s[i]%10;
}
}
void sc()
{
int w;
for(int i=0;i<=100;i++)
{
if(s[i]!=0)
{
w=i;
break;
}
}
for(int i=w;i<=100;i++)
printf("%d",s[i]);
}
int main()
{
scanf("%d",&n);
s[100]=a[100]=1;
for(int i=2;i<=n;i++)
{
change(i);
qh();
}
sc();
return 0;
}

https://www.cnblogs.com/jaszzz/p/12722445.html
剪枝操作

相关标签: 算法