为什么会爆零?

P1591 阶乘数码

gzw2005 @ 2018-06-12 21:33:23

貌似并没有错。。

#include<bits/stdc++.h>
using namespace std;
int num[3000],numN,cnt,n,f;
int main(){
    int t;scanf("%d",&t);
    while(t--){
        memset(num,0,sizeof(num));//清零 
        num[1]=numN=1;cnt=0;
        scanf("%d%d",&n,&f);
        for(int i=2;i<=n;i++){//高精度 
            for(int j=1;j<=numN;j++)
                num[j]*=i;
            for(int j=1;j<=numN;j++){
                num[j+1]+=num[j]/10;
                num[j]%=10;
            }
            if(num[numN+1])numN++;
        }
        for(int i=1;i<=numN;i++)//判断 
            if(num[i]==f)cnt++;
        printf("%d\n",cnt);
    }
    return 0;
}

by Burnside @ 2018-08-20 21:01:48

@突然颓废 已经给您改成ac代码了,中间有错误的地方已经注释上了。

#include<bits/stdc++.h>
using namespace std;
int num[3000],numN,cnt,n,f;
int main(){
    int t;scanf("%d",&t);
    while(t--){
        memset(num,0,sizeof(num));
        num[1]=numN=1;cnt=0;
        scanf("%d%d",&n,&f);
        for(int i=2;i<=n;i++){
            for(int j=1;j<=numN+5;j++)
                num[j]*=i;
            for(int j=1;j<=numN+5;j++){//这个地方,因为乘数已经达到了100以上,所以有可能会一次进两位,如果j<=numN并且下面只进行num[j+1]的判断的话是不行的,最好多判断几位。
                num[j+1]+=num[j]/10;
                num[j]%=10;
            }
            for(int j=numN+5;j>=1;j--)//这个地方,当初您是判断的第numN+1位有没有数字,也是像刚刚讲到的那样,进位超过一位了之后是错误的。而且最好不要正着一位一位判断数列长度,因为如果我有一位恰好是0,那么我判断出来的长度是不正确的。先让j远远大于它可能的进位,然后倒着找第一个大于0的数,才能准确无误地判断数列长度。
                if(num[j]){
                    numN=j;
                    break;
                }
        }
        for(int i=1;i<=numN;i++)
            if(num[i]==f)cnt++;
        printf("%d\n",cnt);
    }
    return 0;
}

如果还有什么不明白的地方可以艾特我 但本人比较弱 有说的不好的地方还请多多指教qwq


by gzw2005 @ 2018-08-23 14:26:12

@Burnside 谢谢大佬


|