一本通1172:求10000以内n的阶乘

【题目描述】


求10000以内n的阶乘。

【输入】


只有一行输入,整数n(0<=n<=10000)。

【输出】


一行,即n!的值。

【输入样例】


4

【输出样例】


24

时间限制: 1000 ms 内存限制: 65536 KB

【代码】

先摆上正确的代码:

#include<bits/stdc++.h>
using namespace std;
int a[40000],h;                 //记录最高位,节省时间
void f(int n){                  //函数递归
    if(n==1){a[0]=1;return;}
    f(n-1);
    int x=0;
    for(int i=0;i<=h+4;i++){    //利用x记录进位,一次循环搞定
        a[i]*=n;                //n小,直接乘
        a[i]+=x;
        x=a[i]/10;
        a[i]%=10;
    }
    h+=4;
    while(!a[h])h--;
}
int main(){
    int n;
    cin>>n;
    f(n);
    for(int i=h;i>=0;i--)cout<<a[i];
    return 0;
}

或者直接用循环

#include<bits/stdc++.h>
using namespace std;
int a[36000],h;      
int main(){
	int n;
	cin>>n;
	a[0]=1;
	for(int k=2;k<=n;k++){
		int x=0;
		for(int i=0;i<=h+4;i++){
			a[i]*=k;
            a[i]+=x;
            x=a[i]/10;
            a[i]%=10;
		}
		h+=4;
		while(!a[h])h--;
	}
    for(int i=h;i>=0;i--)cout<<a[i];
    return 0;
}

【做题过程】

这题难度很小,最基本的高精度计算。

关键是时间的问题,要注意,一不小心最后两个点就超时了。

下面是一步步改正的过程:

最开始的代码是这样的:

#include<bits/stdc++.h>
using namespace std;
int a[40000],c[40000];
void f(int n){
	if(n==0){
		a[0]=1;
		return;
	}
    f(n-1);
    int b[5];
    for(int i=0;i<5;i++)b[i]=n%10,n/=10;
    for(int i=0;i<40000;i++){
        for(int j=0;j<5;j++){
            c[i+j]+=a[i]*b[j];
        }
    }
    for(int i=0;i<40000;i++){
        if(c[i]>=10)c[i+1]+=c[i]/10,c[i]%=10;
        a[i]=c[i];
        c[i]=0;
    }
    return;
}
int main(){
    int n;
    cin>>n;
    f(n);
    int l=39999;
    while(!a[l])l--;
    for(;l>=0;l--)cout<<a[l];
    return 0;
}

但最后两个点超时了。

然后想了一下,n其实很小,数组b没有存在的必要。

#include<bits/stdc++.h>
using namespace std;
int a[40000],c[40000];
void f(int n){
    if(n==1){a[0]=1;return;}
    f(n-1);
    for(int i=0;i<40000;i++){
        c[i]+=a[i]*n;
    }
    for(int i=0;i<40000;i++){
        if(c[i]>=10)c[i+1]+=c[i]/10,c[i]%=10;
        a[i]=c[i];
        c[i]=0;
    }
}
int main(){
    int n;
    cin>>n;
    f(n);
    int l=39999;
    while(!a[l])l--;
    for(;l>=0;l--)cout<<a[l];
    return 0;
}

不过改了之后仍然没有过,后两个点依然超时了。

于是又想了一些办法改进:

记录位数,不仅可以大大减少函数f中的循环次数,主函数也中不用再循环一次去掉前导0;

删去c[40000],将函数f中的两次循环合并,此时需要用x记录进位。

这样就得到了最终的正确代码。

c++初学者,第一次写博客,请大家多多指教!

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值