25分求调

P1009 [NOIP1998 普及组] 阶乘之和

JX_Oier114514 @ 2024-10-11 23:01:33

1,3,4点没过,但是1~50的结果用计算器算了,输出没有问题,但不知道为什么过不了测试点,球球大佬修改


#include<bits/stdc++.h>
using namespace std;
const int MAXN=1000;
long long n,sum[MAXN],a[MAXN];
bool f=0;
int main()
{
    cin>>n;
    a[1]=sum[1]=1;
    if(n==0||n==1)
    {
        cout<<"1";
        return 0;
    }
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=MAXN;j++)
            a[j]*=i;
        for(int j=1;j<=MAXN;j++)
        {
            a[j+1]+=a[j]/10;
            a[j]%=10;
        }
        for(int j=1;j<=MAXN;j++)
        {
            sum[j]+=a[j];
            sum[j+1]+=sum[j]/10;
            sum[j]%=10;

        }

    }
    for(int i=MAXN;i>=1;i--)
    {
        if(sum[i]!=0)
            f=1;
        if(f)
            cout<<sum[i];

    }
    return 0;
 } 

```

by luogu_00 @ 2024-10-12 17:49:31

long long 改成 unsigned long long ,因为阶乘算出来的不会是负数,使用 unsigned 的话无法表示负数,但可以表示正数的范围翻了一番。


by JX_Oier114514 @ 2024-10-12 23:42:04

@luogu_00 谢谢大佬QAQ,不过后面发现是sum和a数组开小了一位导致数组炸了的问题(

const int MAXN=1000;
long long n,sum[MAXN],a[MAXN];//a,sum数组的长度为1000,也就是下标是从0~999;
for(int i=MAXN;i>=1;i--)//但是这里的i最大到达了1000,超出了数组的范围
    {
        if(sum[i]!=0)
            f=1;
        if(f)
            cout<<sum[i];

    }

所以只需要将数组再开大一位就可以了,感觉oi白学了(


by luogu_00 @ 2024-10-15 20:28:09

@JX_Oier114514 非常简单,就这样:

const int MAXN=1001; //把MAXN调大一位
long long n,sum[MAXN],a[MAXN]; // 数组下表0~1000
bool f; // f不能不见,否则Compliare error
for(int i=MAXN-1;i>=1;i--){ // 这下不会越界了
    if(sum[i]!=0)
        f=1;
    if(f)
        cout<<sum[i];
}

by JX_Oier114514 @ 2024-10-15 22:25:20

@luogu_00 谢谢大佬


|