这道题一看我知道如果我的第一思路,递归调用函数肯定超时,数太大,于是我就想到了打表。。想开一个二维数组。。可惜。数组太大开不了。这个思路错误的。
在google 搜索了下,在网易博客发现一种超级好的办法。自己的见识太少了。原来对于求大整数的阶乘,可以采用分段相乘的方法,其理论基础是加法的分配律,乘法的分配律。万分感谢。。高人博客网址。
http://happylch21.blog.163.com/blog/static/16563975920106209118434/
现附上他的代码:
#include
<
stdio.h
>
int main()
{
int n,j,i,t,p,sum;
int result[ 16000 ];
while (scanf( " %d " , & n) != EOF){
t = p = 0 ;result[ 0 ] = 1 ; // t记录result中所存数的个数
for (j = 1 ;j <= n;j ++ ){ // n!=1*2*3*4...*n;
for (i = 0 ;i <= t;i ++ ){
result[i] = result[i] * j + p;p = 0 ; // 如果sum>99999不成立,则不需进位,进位为0
if (result[i] > 99999 ){
p = result[i] / 100000 ; // 进位
result[i] %= 100000 ; // 数组sum中每位存5位数字
if (t == i){t ++ ;result[t] = p;p = 0 ; break ;} // t在最高位有进位的情况下++,最高位存进位 ,并让进位为0
// 如果进位不为0, 则下一次乘的时候将加上该进位,显然不合理
}
}
}
printf( " %d " ,result[t]); // 先把最高位输出,因为最高位没有前导0
for (i = t - 1 ;i >= 0 ;i -- )
printf( " %05d " ,result[i]); // s[i]不足5位,说明需补0 也说明result[i]在对100000取余的时候去掉了前导0,所以这里要加上
printf( " \n " );
}
return 0 ;
}
int main()
{
int n,j,i,t,p,sum;
int result[ 16000 ];
while (scanf( " %d " , & n) != EOF){
t = p = 0 ;result[ 0 ] = 1 ; // t记录result中所存数的个数
for (j = 1 ;j <= n;j ++ ){ // n!=1*2*3*4...*n;
for (i = 0 ;i <= t;i ++ ){
result[i] = result[i] * j + p;p = 0 ; // 如果sum>99999不成立,则不需进位,进位为0
if (result[i] > 99999 ){
p = result[i] / 100000 ; // 进位
result[i] %= 100000 ; // 数组sum中每位存5位数字
if (t == i){t ++ ;result[t] = p;p = 0 ; break ;} // t在最高位有进位的情况下++,最高位存进位 ,并让进位为0
// 如果进位不为0, 则下一次乘的时候将加上该进位,显然不合理
}
}
}
printf( " %d " ,result[t]); // 先把最高位输出,因为最高位没有前导0
for (i = t - 1 ;i >= 0 ;i -- )
printf( " %05d " ,result[i]); // s[i]不足5位,说明需补0 也说明result[i]在对100000取余的时候去掉了前导0,所以这里要加上
printf( " \n " );
}
return 0 ;
}