题目一
基本思路
1.四位数阶乘结果肯定爆掉long long 了,一定是高精度乘法;
2.我们发现没一个数字都是小的数字,但是累积结果是大数字,所以很难用字符串,考虑不用字符串;
3.我们依然要用三个数组,一个a[]用来存结果,b[]存乘数(很大),c[]用来存临时乘积;强调:一定要有c这个数组,因为C一直在参加计算,会覆盖掉原来的值,最后把c的值赋给a就行
关键点
1.c数组赋值a数组一定都要保持低位在前;
2.模块那里每次都从0开始遍历看起来会重复,但其实数据没重复,重复的只是过程
我的代码
#include<stdio.h>
#include<string.h>
int main()
{
int t;
scanf("%d",&t);
//要输出数字组数为t
while(t--){
int a[5005]={1},b[5005],c[10010];//a数组保存阶乘结果,b数组保存乘数,c数组保存a*b临时结果
int n,target;//定义
scanf("%d %d",&n,&target);
int lenA=1;
int x,i;
int temp;
int lenB,lenC;//这两个长度在后面的乘法模块要用到
for(x=2;x<=n;x++){
temp=x;//这里用一个临时变量存
lenB=0;
while(temp>0){
b[lenB++] = temp % 10; //确保b数组每一个数都是个位数
temp /= 10; //temp每一位数字都要变成b数组一个数单元
}
int j;
memset(c, 0, sizeof(c));//这里是初始化c数组为0 ,相比遍历赋值更简单
for(i=0;i<lenA;i++){
//下面这一块高精度乘法经典模块
for(j=0;j<lenB;j++){
c[i+j]+=a[i]*b[j];
}
for(j=0;j<lenB;j++){
c[i+j+1]+=c[i+j] / 10;
c[i+j] %= 10;
}
}
int lenC=lenA+lenB;
while(lenC>1 && c[lenC-1]==0){
lenC--;//去掉前导零
}
for(i=0;i<lenC;i++){
a[i]=c[i];//这里千万不要倒着赋值,只有输出的时候需要倒过来。保持低位在前。
}
lenA=lenC;
}
int cnt=0;
for(i=0;i<lenA;i++){
if(a[i]==target) cnt++;
}
printf("%d\n",cnt);
}
return 0;
//写完这一篇了,我感觉让我做我还是做不出来,我明天会再来尝试做这道题,结果我会写到明天文章
}