今天开始做做算法的题目,在51NOD网站上。(本人是刚入手oj的小菜鸟)想以博客形式记录下自己的写过的题目,加一总结。题目如下所示:
Input
输入N(1 <= N <= 10000)
Output
输出N的阶乘
Input示例
5
Output示例
120
看到题目我一脸懵逼,自己脑海里面最大的数就是long long 我以为就直接这样写就可以了就有了如下的代码:
#include<cstdio>
int main()
{
int a;
long long b;
scanf("%d",&a);
for(int i=1;i<=a;i++)
{
b*=i;
}
printf("%lld",b);
}
然而结果却不是我想要的正确。题目是小于10000的阶乘远远大于long long 2的64次方,怎么办呢我想不到了,不知道如何处理于是我开始百度找到了别人的解法。
1. #include<cstdio>
2. #include<cstring>
3. #include<cmath>
4. #include<algorithm>
5. using namespace std;
6.
7. #define _MAX 100000000
8. long long a[10005];
9. int main()
10. {
11. int i,j,n,m = 0; //m与切片有关,c与进位有关
12. long long c; //当C>0时,即代表进位
13. a[0] = 1; //不要忘记,0! = 1
14. scanf("%d",&n);
15. for(i=1; i<=n; i++)
16. {
17. c = 0;
18. for(j = 0; j<=m; j++)
19. {
20. a[j] = a[j] * i + c;
21. c = a[j] / _MAX;
22. a[j] = a[j] % _MAX;
23. }
24. if(c > 0)
25. {
26. m++;
27. a[m] = c;
28. }
29. }
30. printf("%lld",a[m]); //先输出首位
31. for(i = m - 1; i>=0; i--)
32. {
33. printf("%08lld",a[i]); //不足指定宽度前面补零
34. }
35.
36.
37.
38.
39.
40. return 0;
41. }
刚开始看这个代码的时候我也不懂后来把从1加到10慢慢按照两个for循环来笔算。就有了一点思路。
这个不就是和平时的10进制的乘法是一样的平时我们是一位一位的上面的代码是8位的。比如说16*6
就把这个16分开来分为10和6。首先6*6是36然后36/10=3是进位。36%10=6是个位的。然后1*6+3是十位的数。代码中的c就是进位,a【m】里面放的就是下一个位的数。比如这个16*6是两位就是m的值2,a【1】=9,a【0】=6;然后输出就可以了。
第一次写博客,请大家多多指教。