C++ 为什么我得到了大输入的错误答案

C++ 为什么我得到了大输入的错误答案,c++,C++,给你一个正方形的n×n图。地图的每个单元格中都有一个值,表示相应区域的深度。当且仅当贴图的一个单元不在贴图的边界上且相邻的每个单元深度都较小时,我们将其称为空洞。如果两个单元格有共同的一面,则它们是相邻的 你需要在地图上找到所有的洞,并用字符X描绘它们 输入格式 第一行包含一个整数n1≤N≤100,表示地图的大小。以下n行中的每一行都包含n个不带空格的正数字。数字1-9表示适当区域的深度 输出格式 输出n行,表示生成的映射。每个空腔应替换为字符X 样本输入 4 1112 1912

给你一个正方形的n×n图。地图的每个单元格中都有一个值,表示相应区域的深度。当且仅当贴图的一个单元不在贴图的边界上且相邻的每个单元深度都较小时,我们将其称为空洞。如果两个单元格有共同的一面,则它们是相邻的

你需要在地图上找到所有的洞,并用字符X描绘它们

输入格式

第一行包含一个整数n1≤N≤100,表示地图的大小。以下n行中的每一行都包含n个不带空格的正数字。数字1-9表示适当区域的深度

输出格式

输出n行,表示生成的映射。每个空腔应替换为字符X

样本输入

 4
 1112   
 1912 
 1892
 1234
样本输出

 1112
 1X12
 18X2
 1234
现在,我做了这个代码。但对于较大的值,这显示了不正确的答案,即n的值为99、100或96

这基本上是获取输入数字,并将输入数组的每一行划分为单独的数字。然后将每个数字与下一个和上一个数字进行比较,以检查其是否大于或小于所考虑的数字。然而,对于n的大值,它显示了错误的答案

这是工作代码。在样本输入上工作良好

#include <iostream>
#include <cmath>
#include <cstdio>

using namespace std;

int main(void) {
    int n, i = 0;
    cin >> n;
    int values[1000];
    int j;
    for (i = 0; i < n; i++) {
        int p;
        cin >> p;
        values[i] = p;
    }
    char digits[1000][1000];
    int foo;
    for (i = 0; i < n; i++) {
        foo = n - 1;
        while (values[i] != 0) {
            digits[i][foo] = values[i] % 10 + 48;
            values[i] = values[i] / 10;
            foo--;
        }
    }

    for (i = 1; i < n - 1; i++) {
        j = 1;
        while (j != n - 1) {
            if (digits[i][j] > digits[i][j - 1] &&
                digits[i][j] > digits[i][j + 1]) {
                digits[i][j] = 'X';
            }
            j++;
        }
    }

    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("%c", digits[i][j]);
        }
        printf("\n");
    }
    return 0;
}
对于较大的输入值,如n值为96或100,这表明回答不正确。我不明白为什么?有什么方法可以优化它吗

不适用于上述输入


附:这不是家庭作业问题。我猜不出怎么解决它

您只检查两个相邻的单元格。每个单元有四个相邻单元:左、右、上、下。您还需要检查顶部和底部单元格,如下所示:

if ( digits[i][j] > digits[i][j-1] && digits[i][j] > digits[i][j+1] && digits[i][j] > digits[i-1][j] && digits[i][j] > digits[i+1][j] )
{
    digits[i][j] = 'X';
}

代码中的一些问题:

在问题中提供的输入内容中,数字位于由int类型变量表示的范围内,但是由链接提供的文件引用中的数字内容超出了C++中任何整数类型的范围。您需要能够存储最多100位数字。这是问题的主要原因,是每行的数字。您可以将其视为std::字符串来解决。 根据问题的描述,需要检查相邻上下单元。 一些改进:

使用std::vector代替C数组。不需要浪费未使用的内存,顺便说一句,在问题的陈述中,他们说行数将在1到100之间,您可以将声明的值和数字变量设置为该长度,向量管理他们的内存在需要时自动增长,他们可以检查越界索引,等等。。。 使用std::string而不是int,阅读前面的原因。 使用std::getline逐行读取文件。 std::string的值可以作为char进行比较,因为它们是数字,“0”=0x30..”9'=0x39,数字的相同顺序适用于其字符表示。 使用C++11对GCC 4.9.0进行了代码测试:

#include <iostream>
#include <vector>

int main(int argc, char* argv[]) {
    unsigned int lines;
    std::cin >> lines;

    std::vector<std::string> values;
    values.reserve(lines);

    // Reading the matrix
    std::string line;
    std::getline(std::cin, line); // Reading the rest of the first line
    while (std::getline(std::cin, line)) {
        values.push_back(line);
    }

    // Checking the depths and marking the cavities
    for (unsigned int i = 1; i < values.size() - 1; i++) {
        const auto& actual_number = values[i];
        for (unsigned int j = 1; j < actual_number.size() - 1; j++) {
            if (actual_number[j] > actual_number[j - 1] &&
                actual_number[j] > actual_number[j + 1] &&
                actual_number[j] > values[i - 1][j] &&
                actual_number[j] > values[i + 1][j]) {
                values[i][j] = 'X';
            }
        }
    }

    // Printing output
    for (const auto& n : values) {
        std::cout << n << std::endl;
    }
    return 0;
}
对于大样本输入文件,输出是相同的数字,因为它们都是9,没有一个更大

使用提供的代码作为基础的版本:

#include <iostream>
#include <cmath>
#include <cstdio>

using namespace std;
int main(void) {
    int n, i = 0;
    cin >> n;
    char values[100][100]; // changed the limit
    int j;
    for (i = 0; i < n; i++) {
        cin >> values[i]; // reading the line. 'int p;' not necessary
    }

    // declaration of digits, and initialization not necessary

    for (i = 1; i < n - 1; i++) {
        j = 1;
        while (j != n - 1) {
            if (values[i][j] > values[i][j - 1] &&
                values[i][j] > values[i][j + 1] &&
                values[i][j] > values[i - 1][j] &&
                values[i][j] > values[i + 1][j]) {
                values[i][j] = 'X';
            }
            j++;
        }
    }

    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("%c", values[i][j]);
        }
        printf("\n");
    }
    return 0;
}

定义两个数组是个坏主意,其中一个数组的元素类型为int

这是一个简单的解决方案,满足您的任务条件 程序逐行读取输入。首先,它读取带有贴图大小编号的第一行,并将其转换为size\t类型的对象。 然后,默认情况下,它使用字符“0”初始化大小为n*n的映射

for ( size_t i = 0; i < n; i++ )
{
    std::memset( map[i], '0', n );
}
由于输入可能是错误的,并且一行可能包含多于或少于n个字符,因此我们从读取行中提取n个字符,并将其复制到行中

事实上,在那之后,任务就完成了。您只需比较贴图中大于调整后元素的每个元素

#include <iostream>
#include <string>
#include <cstring>

int main() 
{
    const size_t N = 100;
    char map[N][N];

    std::string line;
    std::getline( std::cin, line );

    size_t n = std::stoul( line );
    if ( N < n ) n = N;

    for ( size_t i = 0; i < n; i++ )
    {
        std::memset( map[i], '0', n );
    }

    for ( size_t i = 0; i < n && std::getline( std::cin, line ); i++ )
    {
        line = line.substr( 0, n );
        std::memcpy( map[i], line.c_str(), line.size() );
    }

    std::cout << n << std::endl;
    for ( size_t i = 0; i < n; i++ )
    {
        for ( size_t j = 0; j < n; j++ ) std::cout << map[i][j] << ' ';
        std::cout << std::endl;
    }
    std::cout << std::endl;

    for ( size_t i = 1; i + 1 < n; i++ )
    {
        for ( size_t j = 1; j + 1 < n; j++ )
        {
            if ( map[i][j-1] < map[i][j] &&
                 map[i][j+1] < map[i][j] &&
                 map[i-1][j] < map[i][j] &&
                 map[i+1][j] < map[i][j] )
            {
                map[i][j] = 'X';
            }
        }
    }

    for ( size_t i = 0; i < n; i++ )
    {
        for ( size_t j = 0; j < n; j++ ) std::cout << map[i][j] << ' ';
        std::cout << std::endl;
    }
    std::cout << std::endl;

    return 0;
}

什么是不正确的输出?你知道你有从int到char的隐式转换吗?@quantdev,不正确的输出意味着我的代码没有通过前面提到的测试用例。我知道,但是因为我打印的是一个字符数组,所以我添加了ASCII值。不相关的:从一个肾上腺素的垃圾到另一个,一个接近兆字节的本地数组?感觉有点大胆?如果这确实是您的输入文件格式,您需要认真检查您的输入验证。@WhozCraig,大小在这里并不重要。@user3845968 Um。。好的,通过包含这个条件,它通过了更多的测试用例,但它仍然在我附加的链接的输入上显示了错误的答案。你看到其他错误了吗?我对C++是新的,因为你可能猜到了,因为我的代码和C几乎是一样的。我想问一件事。我们是否可以像您所做的那样像解析简单数组一样解析字符串?比如,实际的_数[j]?是的,调用std::string的索引运算符将得到字符串中该位置的字符。还有一件事,为什么要使用const auto&actual_数=value[i];。const是什么意思
自动&在这里?在打印时,我在循环中理解了您为什么使用const auto&这篇文章:http://stackoverflow.com/questions/19414299/meaning-of-auto.auto 是对C++11标准的新添加,这意味着编译器将根据赋值推断变量的类型。在这种情况下,它意味着const std::string&,实际的_编号将通过引用保存不可修改的std::string,这对于避免不必要的副本很重要。values.reserve,为什么要使用它?这不是有点不必要吗?另外,因为当我读它的时候,我无法理解它,因为我是初学者,所以对我来说太难理解了。请补充一些解释。谢谢我知道我要求太多了。但再次感谢你
#include <iostream>
#include <string>
#include <cstring>

int main() 
{
    const size_t N = 100;
    char map[N][N];

    std::string line;
    std::getline( std::cin, line );

    size_t n = std::stoul( line );
    if ( N < n ) n = N;

    for ( size_t i = 0; i < n; i++ )
    {
        std::memset( map[i], '0', n );
    }

    for ( size_t i = 0; i < n && std::getline( std::cin, line ); i++ )
    {
        line = line.substr( 0, n );
        std::memcpy( map[i], line.c_str(), line.size() );
    }

    std::cout << n << std::endl;
    for ( size_t i = 0; i < n; i++ )
    {
        for ( size_t j = 0; j < n; j++ ) std::cout << map[i][j] << ' ';
        std::cout << std::endl;
    }
    std::cout << std::endl;

    for ( size_t i = 1; i + 1 < n; i++ )
    {
        for ( size_t j = 1; j + 1 < n; j++ )
        {
            if ( map[i][j-1] < map[i][j] &&
                 map[i][j+1] < map[i][j] &&
                 map[i-1][j] < map[i][j] &&
                 map[i+1][j] < map[i][j] )
            {
                map[i][j] = 'X';
            }
        }
    }

    for ( size_t i = 0; i < n; i++ )
    {
        for ( size_t j = 0; j < n; j++ ) std::cout << map[i][j] << ' ';
        std::cout << std::endl;
    }
    std::cout << std::endl;

    return 0;
}
4
1 1 1 2 
1 9 1 2 
1 8 9 2 
1 2 3 4 

1 1 1 2 
1 X 1 2 
1 8 X 2 
1 2 3 4