燕子的代码很巧妙。。。
#include<stdio.h>
#define N 1000
//要计算的N
long s[N]={1,1},n=N,t=2,a=1,b=0;
int main()//
{
for(;a<=*s||(++t<=n?(b=0,a=1):0);(*s==a++&&b)?(*s)++:0)
s[a]=(b+=s[a]*t)%10000,b/=10000;
for(printf("%d",s[*s]);--*s>0;)printf("%04d",s[*s]);
return 0;
}
把数组得第0位用来纪录数组长度。。
t是当前的要乘的数。。
b是进位标志。。。
a是数组下标。。。
数组的每位长度为4。。
开始分析:
第一次的时候:a=1,b=0;s[0]=1;
a<=s[0] 真
所以执行下面
s[a]=(b+=s[a]*t)%10000,b/=10000;
可分解为
b=s[a]*t+b;
s[a]=(b)%10000;
b=b/10000;
接着判断
(*s==a++&&b)?(*s)++:0
s[0]==a是真,b=0
a++;
表达式为假,a++,a=2;
再次进入循环
a<=s[0]?2<1是假。。所以做后面
(++t<=n?(b=0,a=1):0)
++t,同时清进位和把数组下标移到第一位从新开始。。。
。。。
直到
(*s==a++&&b)?(*s)++:0为真的时候,数组长度增加一个。。。
整个思想是用数组来模拟大数,然后做乘运算。。