当数组大小过大例如大小 >= 800但在在线编译器中工作正常时,C++ 代码不显示输出

问题描述

我不明白为什么会这样。

代码运行良好,但当我采用大数组时,它不会在我的系统中显示输出,而另一方面,它会在在线编译器中提供正确的输出

如果我采用较小的数组大小,它可以正常工作并在我的系统中显示输出

#define N 805

这里是 C++ 语言的代码

#include<bits/stdc++.h>
using namespace std;
 
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL);
#define M 1000000007
#define N 805
#define ll long long int
 
void init_start(){
    fast_io;
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
}
 
int main()
{
    init_start();
    int n,k,limi;
    cin>>n>>k;
    
    int n_arr[N][N];
    int k_arr[N][N];

    for (int i = 0; i < N; i++)
    {
        k_arr[i][0]=0;
        k_arr[0][i]=0;
    }
 
    int mini = -1,maxi = 1000000000,mid;
    bool check;
    limi = ((k*k) / 2) + 1;
 
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            cin >> n_arr[i][j];
        }
        
    }
     while((mini + 1) < maxi)
     {
        mid = (mini + maxi) / 2;
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                k_arr[i+1][j+1] = k_arr[i+1][j] + k_arr[i][j+1] - k_arr[i][j];
                if(n_arr[i][j] > mid)
                {
                    k_arr[i+1][j+1]++;
                }
            }
        }
        check = false;
        for (int i = 0; i < n-k+1; ++i)
        {
            for (int j = 0; j < n-k+1; ++j)
            {
                if ((k_arr[i+k][j+k] + k_arr[i][j] - k_arr[i][j+k] - k_arr[i+k][j])<limi)
                {
                    check = true;
                }
            }
        }
        if (check)
            {
                maxi = mid;
            }
            else
            {
                mini = mid;
            }
     }
     cout << maxi << endl;
    return 0;
}

解决方法

int n_arr[N][N];
int k_arr[N][N];

我怀疑您的本地环境配置的堆栈大小比在线环境小。将 N 设置为 805 并使用 32 位整数,这将消耗大约 5M 的堆栈,相当多。

您可能需要考虑使用堆,它通常限制较少(newdelete)。一个简单的解决方案是将第一个维度保留在堆栈上(805 个指针还不错),但将堆用于第二个维度,例如:

int *n_arr[N],*k_arr[N];
for (int i = 0; i < N; ++i) {
    n_arr[i] = new int[N];
    k_arr[i] = new int[N];
}

// Use them here as you currently do,e.g.,n_arr[42][99].

for (int i = 0; i < N; ++i) {
    delete [] n_arr[i];
    delete [] k_arr[i];
}

更好的 C++ 解决方案可能是使用 std::vector,或者查找/创建一些描述的基于堆的矩阵类。

,
#include<bits/stdc++.h>

避免滥用实现定义的标头。这个头文件的目的是在预编译头文件中使用。

using namespace std;

避免在命名空间范围内使用它。更喜欢使用范围解析运算符。

#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL);

避免像这样混淆程序。更喜欢使用函数。

#define M 1000000007
#define N 805

避免对常量使用宏。更喜欢(常量)变量。

#define ll long long int

避免使用宏作为类型别名。更喜欢 typedef/using

除非没有更好的替代方案(通常有),否则完全避免使用宏。

此外,除了模板用途外,最好避免完全使用类型别名。 long long 不需要打多少字,读者一看就知道它是什么类型。


可用于自动变量的大小在大多数系统上通常非常有限。您应该避免使用大型自动对象,因为它们可能会导致...堆栈溢出

int n_arr[N][N];

这是一个自动变量。它是巨大的。在某些系统上很可能会溢出堆栈。避免这样做。

对于这个程序,最简单的解决方案是使用静态存储而不是自动存储。