洛谷P1009题解

文章详细介绍了如何使用C++实现高精度阶乘计算,包括两种方法:一种是用`unsignedlonglong`处理,另一种是利用字符串进行高精加法和高精乘法操作。通过模拟阶乘相加和阶乘计算,确保了结果的准确性。
摘要由CSDN通过智能技术生成

题目传送门

是否要用高精?

虽然50看上去不是很大,但是它的阶乘之和却达到了31035053229546199656252032972759319953190362094566672920420940313(三百一十万零三千五百零五亿三千二百二十九万五千四百六十一亿九千九百六十五万六千二百五十二亿零三百二十九万七千二百七十五亿九千三百一十九万九千五百三十一亿九千零三十六万二千零九十四亿五千六百六十六万七千二百九十二亿零四百二十万零九千四百零三*一百+十三)

所以——一定要用高精!!!

50分

思路

如果你不会高精,用unsigned long long ,能得50分(long long也能得50分)

代码:

#include<iostream>
using namespace std;
unsigned long long a,ans=0;
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
    	a=1;
        for(int j=1;j<=i;j++){
        	a*=j;
		}
		ans+=a;
    }
    cout<<ans;
    return 0;
}

100分 

思路

高精加(阶乘相加时用)+高精乘(计算阶乘时用)模拟,计算的ans要用string类型。

代码

高精加

string g_jia(string a,string b){
	int lena=a.length(),lenb=b.length();
	if(lena<lenb){
		for(int i=1;i<=lenb-lena;i++)a='0'+a;
	}else{
		for(int i=1;i<=lena-lenb;i++)b='0'+b;
	}lena=a.length(),lenb=b.length();
	int lens=lena;
	int jw=0,cnt=0;
	string ans;
	for(int i=lens-1;i>=0;i--){
		cnt=a[i]-'0'+b[i]-'0'+jw;
		jw=cnt/10;
		cnt%=10;
		ans=char(cnt+'0')+ans;
	}if(jw){
		ans=char(jw+'0')+ans;
	}return ans;
}

 高精乘

string g_cheng(string a1,string b1){
	string ans;
	int c[100001],a[100001],b[100001];
	memset(c,0,sizeof(c));
	int lena=a1.length();
	int lenb=b1.length();
	for(int i=1;i<=lena;i++)a[i]=a1[lena-i]-'0';
	for(int i=1;i<=lenb;i++)b[i]=b1[lenb-i]-'0';
	for(int i=1;i<=lenb;i++){
		for(int j=1;j<=lena;j++){
			c[i+j-1]+=a[j]*b[i];
		}
	}for(int i=1;i<lena+lenb;i++){
		if(c[i]>9){
			c[i+1]+=c[i]/10;
			c[i]%=10;
		}
	}int lens=lena+lenb;
	while(c[lens]==0&&lens>1)lens--;
	for(int i=lens;i>0;i--){
		ans+=(c[i]+48);
	}return ans;
}

主函数

int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		string lin=g_jia("0","1");
		for(int j=1;j<=i;j++){
			int k=j;
			string s;
			while(k){
				char ls=char(k%10+48);
				s=ls+s;
				k/=10;
			}lin=g_cheng(lin,s);
		}a=g_jia(a,lin);
	}cout<<a;
	return 0;
}

 完整代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<deque>
using namespace std;
int n;
string a="0";
string g_cheng(string a1,string b1){
	string ans;
	int c[100001],a[100001],b[100001];
	memset(c,0,sizeof(c));
	int lena=a1.length();
	int lenb=b1.length();
	for(int i=1;i<=lena;i++)a[i]=a1[lena-i]-'0';
	for(int i=1;i<=lenb;i++)b[i]=b1[lenb-i]-'0';
	for(int i=1;i<=lenb;i++){
		for(int j=1;j<=lena;j++){
			c[i+j-1]+=a[j]*b[i];
		}
	}for(int i=1;i<lena+lenb;i++){
		if(c[i]>9){
			c[i+1]+=c[i]/10;
			c[i]%=10;
		}
	}int lens=lena+lenb;
	while(c[lens]==0&&lens>1)lens--;
	for(int i=lens;i>0;i--){
		ans+=(c[i]+48);
	}return ans;
}string g_jia(string a,string b){
	int lena=a.length(),lenb=b.length();
	if(lena<lenb){
		for(int i=1;i<=lenb-lena;i++)a='0'+a;
	}else{
		for(int i=1;i<=lena-lenb;i++)b='0'+b;
	}lena=a.length(),lenb=b.length();
	int lens=lena;
	int jw=0,cnt=0;
	string ans;
	for(int i=lens-1;i>=0;i--){
		cnt=a[i]-'0'+b[i]-'0'+jw;
		jw=cnt/10;
		cnt%=10;
		ans=char(cnt+'0')+ans;
	}if(jw){
		ans=char(jw+'0')+ans;
	}return ans;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		string lin=g_jia("0","1");
		for(int j=1;j<=i;j++){
			int k=j;
			string s;
			while(k){
				char ls=char(k%10+48);
				s=ls+s;
				k/=10;
			}lin=g_cheng(lin,s);
		}a=g_jia(a,lin);
	}cout<<a;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值