C语言问题:请帮我解释一下这个代码的思路
来源:学生作业帮 编辑:神马作文网作业帮 分类:综合作业 时间:2024/11/11 05:42:24
C语言问题:请帮我解释一下这个代码的思路
Description
输入不超过 1000 的正整数 n ,输出 = 1 X 2 X 3 … X n 的精确结果.
Input
多组测试数据,对于每组测试数据输入一个正整数 n.
Output
对于每组测试数据输出一行,表示 的结果.
Sample Input
30
Sample Output
265252859812191058636308480000000
#include
#include
const int maxn = 3003;
int f[maxn];
int main(){
\x09int i,j,n;
\x09while (scanf("%d",&n)!=EOF){
\x09\x09memset( f,0,sizeof(f) );
\x09\x09f[0] = 1;
\x09\x09for (i = 2; i = 0; --j) if ( f[j] ) break;
\x09\x09for (i = j; i >= 0; --i) printf("%d",f[i]);
\x09\x09puts("");
\x09}
\x09return 0;
}
Description
输入不超过 1000 的正整数 n ,输出 = 1 X 2 X 3 … X n 的精确结果.
Input
多组测试数据,对于每组测试数据输入一个正整数 n.
Output
对于每组测试数据输出一行,表示 的结果.
Sample Input
30
Sample Output
265252859812191058636308480000000
#include
#include
const int maxn = 3003;
int f[maxn];
int main(){
\x09int i,j,n;
\x09while (scanf("%d",&n)!=EOF){
\x09\x09memset( f,0,sizeof(f) );
\x09\x09f[0] = 1;
\x09\x09for (i = 2; i = 0; --j) if ( f[j] ) break;
\x09\x09for (i = j; i >= 0; --i) printf("%d",f[i]);
\x09\x09puts("");
\x09}
\x09return 0;
}
估计你是没明白程序中计算!算法那段.
其实这个程序的核心的是用数组存储整数120 f[7]={0,2,1,0,0,0,0},并进一步模拟乘法计算实现并将结果以同样方式存储到数组中的一个模型算法
如5400用int 数组存储为f[0,0,4,5}
下面是阶乘计算:举个列我们计算6! 假设我们已经知道5!是120.实际我们就是计算120*6
我们用数组存整数120以 f[7]={0,2,1,0,0,0,0}形式存储,在用 6乘以他的每一位,cnt表示乘积超过10需要进位的数,
你语句中int s = f[j] * i+ cnt;就是用数组的j位元素(上面f[j]的值)乘以i(6)在加上上一位需要进位的数(10进1)
(j = 0; j < maxn; ++j){
int s = f[j] * i + cnt;
f[j] = s % 10;
cnt = s / 10;
就是用循环实现 数组每一位*i并保证每位保留一位整数且满足乘法规则进位.
具体分步如下: f[7]={0,2,1,0,0,0,0} 120*6 cnt=0
个位:0*6+0=0 最后保存的应该是一位整数:除以10求余实现 0%10=0 结果的f[0]=0; 进位用除10被整除的部分实现 0/10=0 所以cnt=0;(我们算出了各位f[0]=0).
十位:2*6+0=12 最后保存的应该是一位整数:除以10求余实现 12%10=2 结果的f[1]=2; 进位用除10被整除的部分实现 12/10=1 所以cnt=1我们算出了十位f[1]=2).
百位:1*6+1=7 最后保存的应该是一位整数:除以10求余实现 7%10=7 结果的f[2]=7; 进位用除10被整除的部分实现 7/10=0 所以cnt=0我们算出了十位f[0]=2).
我们注意到cnt=0且余下的数组也为0 所以f[3]=f[4]=f[5]=f[6]=f[7]=0;
所以120*6最后结果为 f={0,2,7,0,0,0,0} 720.
OK现在算发讲解完了其余部分就很简单了:for (j = 0; j < maxn; ++j)的循环就是实现当前算组乘以i;for (i = 2; i = 0; --j) if ( f[j] ) break;j--到0这是输出仍然是f[0]=1;
for (i = 2; i = 0; --j)if ( f[j]!=0) break;//计算数的最高位 因为最高位是数组从后到前第一个不为0的数
for (i = j; i >= 0; --i)
printf("%d",f[i]);
puts("");
}
}
其实这个程序的核心的是用数组存储整数120 f[7]={0,2,1,0,0,0,0},并进一步模拟乘法计算实现并将结果以同样方式存储到数组中的一个模型算法
如5400用int 数组存储为f[0,0,4,5}
下面是阶乘计算:举个列我们计算6! 假设我们已经知道5!是120.实际我们就是计算120*6
我们用数组存整数120以 f[7]={0,2,1,0,0,0,0}形式存储,在用 6乘以他的每一位,cnt表示乘积超过10需要进位的数,
你语句中int s = f[j] * i+ cnt;就是用数组的j位元素(上面f[j]的值)乘以i(6)在加上上一位需要进位的数(10进1)
(j = 0; j < maxn; ++j){
int s = f[j] * i + cnt;
f[j] = s % 10;
cnt = s / 10;
就是用循环实现 数组每一位*i并保证每位保留一位整数且满足乘法规则进位.
具体分步如下: f[7]={0,2,1,0,0,0,0} 120*6 cnt=0
个位:0*6+0=0 最后保存的应该是一位整数:除以10求余实现 0%10=0 结果的f[0]=0; 进位用除10被整除的部分实现 0/10=0 所以cnt=0;(我们算出了各位f[0]=0).
十位:2*6+0=12 最后保存的应该是一位整数:除以10求余实现 12%10=2 结果的f[1]=2; 进位用除10被整除的部分实现 12/10=1 所以cnt=1我们算出了十位f[1]=2).
百位:1*6+1=7 最后保存的应该是一位整数:除以10求余实现 7%10=7 结果的f[2]=7; 进位用除10被整除的部分实现 7/10=0 所以cnt=0我们算出了十位f[0]=2).
我们注意到cnt=0且余下的数组也为0 所以f[3]=f[4]=f[5]=f[6]=f[7]=0;
所以120*6最后结果为 f={0,2,7,0,0,0,0} 720.
OK现在算发讲解完了其余部分就很简单了:for (j = 0; j < maxn; ++j)的循环就是实现当前算组乘以i;for (i = 2; i = 0; --j) if ( f[j] ) break;j--到0这是输出仍然是f[0]=1;
for (i = 2; i = 0; --j)if ( f[j]!=0) break;//计算数的最高位 因为最高位是数组从后到前第一个不为0的数
for (i = j; i >= 0; --i)
printf("%d",f[i]);
puts("");
}
}