虽然过了,但是不理解洛谷的IDE什么问题

P1009 [NOIP1998 普及组] 阶乘之和

TraveltTibet @ 2023-04-14 22:24:21

先说问题把: 就是我以下代码的全局变量不同,也就是我设置数组长度得到的结果非常意外,先来一份没问题的代码如下:

//高精度计算n的阶乘,n<=50
#include<iostream>
using namespace std;
#define NUMBER 80
#define MAX 90
//数字要倒序存到数组里面
//高精乘
void GJC(int temp[NUMBER],int temp1[MAX],int c[MAX])
{
    int i,j;
    for(i=0;i<MAX;i++)
    {
        for(j=0;j<=i;j++)
            c[i] +=temp[j]*temp1[i-j];
        //进位
        if(c[i]>=10)
        {
            c[i+1] += c[i]/10;
            c[i] %=10;
        }
    }
}
//高精度加
void GJJ(int temp[MAX],int temp1[MAX],int c[MAX])
{
    int i,j;
    for(i=0;i<MAX;i++)
    {
        c[i] += temp[i]+temp1[i];
        if(c[i]>=10)
        {
            c[i+1] += c[i]/10;
            c[i] %=10;
        }
    }
}
int main()
{
    int a[MAX]={0},b[MAX]={0},n,i,j,sum[MAX]={0},c[MAX]={0},d[MAX]={0};
    cin>>n;
    for(i=1;i<=n;i++)
    {
        if(i==1)
        {
            a[0]=1;
            b[0]=1;
            d[0]=0;
            GJC(a,b,c);
            GJJ(c,d,sum);
            continue;
        }
        for(j=0;j<MAX;j++)
        {
            d[j]=sum[j];
            b[j]=c[j];
            c[j]=0;
            sum[j]=0;
        }
        a[0]=i%10;
        a[1]=i/10;
        GJC(a,b,c);
        GJJ(c,d,sum);
    }
    for(i=NUMBER;i>0;i--)
    {
        if(sum[i]!=0)
            break;
    }
    for(j=i;j>=0;j--)
    {
        cout<<sum[j];
    }
    return 0;
}

然后再来一份有问题的代码,大家重点关注全局变量和GJJ,GJC两个函数的两份代码的差异之处:

//高精度计算n的阶乘,n<=50
#include<iostream>
using namespace std;
#define MAX 90
//数字要倒序存到数组里面
//高精乘
void GJC(int temp[MAX],int temp1[MAX],int c[MAX])
{
    int i,j;
    for(i=0;i<MAX;i++)
    {
        for(j=0;j<=i;j++)
            c[i] +=temp[j]*temp1[i-j];
        //进位
        if(c[i]>=10)
        {
            c[i+1] += c[i]/10;
            c[i] %=10;
        }
    }
}
//高精度加
void GJJ(int temp[MAX],int temp1[MAX],int c[MAX])
{
    int i,j;
    for(i=0;i<MAX;i++)
    {
        c[i] += temp[i]+temp1[i];
        if(c[i]>=10)
        {
            c[i+1] += c[i]/10;
            c[i] %=10;
        }
    }
}
int main()
{
    int a[MAX]={0},b[MAX]={0},n,i,j,sum[MAX]={0},c[MAX]={0},d[MAX]={0};
    cin>>n;
    for(i=1;i<=n;i++)
    {
        if(i==1)
        {
            a[0]=1;
            b[0]=1;
            d[0]=0;
            GJC(a,b,c);
            GJJ(c,d,sum);
            continue;
        }
        for(j=0;j<MAX;j++)
        {
            d[j]=sum[j];
            b[j]=c[j];
            c[j]=0;
            sum[j]=0;
        }
        a[0]=i%10;
        a[1]=i/10;
        GJC(a,b,c);
        GJJ(c,d,sum);
    }
    for(i=MAX;i>0;i--)
    {
        if(sum[i]!=0)
            break;
    }
    for(j=i;j>=0;j--)
    {
        cout<<sum[j];
    }
    return 0;
}

第二份代码的错误形式就很离谱:

例如输入1时,输出为:

1875949600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001

正确的情况应该是1,很离谱对吧,鄙人也不知道哪出问题了,希望有大佬能解惑,在此谢过。。。


by TraveltTibet @ 2023-04-14 22:30:10

在此补充一下,一开始我在Visual Studio Code,gcc 8.1.0 环境下是能运行出正确的答案,然后我再拿到洛谷的在线IDE上测试得到了一些离谱的答案,经过我多次调整全局变量的值,又能正常运行了,所以我不知道是代码内部的问题还是在线IDE或者Visual Studio Code的问题,反正挺疑惑的,之前也遇到过一样的答案,在Visual Studio Code上能正常运行,在洛谷在线IDE却异常的问题。

T_T


by xs_siqi @ 2023-04-14 22:35:00

@TraveltTibet 第二个程序中,显然你的 sum 数组大小为MAX,即 0MAX-1,但你在第六十三行运用了 sum 数组的 MAX 位,数组越界了。但第一个数组是从 80 开始遍历的,所以没越界。


by xs_siqi @ 2023-04-14 22:36:56

@TraveltTibet 所以为了避免越界,把 63 行的 MAX 改为 MAX-1 即可。洛谷IDE上这样改就能通过你说的数据。


by TraveltTibet @ 2023-04-15 18:20:18

感谢你的指正,我这步越界我确实没有发现


|