为什么大的输入会得到错误的答案
Why am I Getting incorrect answer for large inputs
您将获得一个正方形n×n地图。地图的每个单元格都有一个值,表示相应区域的深度。当且仅当该单元不在地图的边界上并且相邻的每个单元的深度都严格小于该单元时,我们将该单元称为空腔。如果两个单元格有共同的边,则它们相邻。
你需要在地图上找到所有的空腔并用字母x来描绘它们
输入格式第一行包含一个整数n(1≤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
。我不明白为什么?有什么方法可以优化它吗?
测试输入文件链接
对上述输入无效
PS:这不是家庭作业问题。我猜不出如何解决这个问题。
您只检查两个相邻的单元格。每个单元格有四个相邻的单元格:左、右、上、下。您还需要像这样检查顶部和底部的单元格:
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,这是一个坏主意。
这是一个满足你的任务条件的简单解程序逐行读取输入。首先,它读取带有map大小编号的第一行,并将其转换为size_t类型的对象。然后初始化大小为n * n的映射,默认使用字符'0'。
for ( size_t i = 0; i < n; i++ )
{
std::memset( map[i], '0', n );
}
使用标准C函数std::memcpy
读取每一行数字并将其复制到映射的对应行
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() );
}
由于输入可能是错误的,并且一行可以包含多于或少于n个字符,因此我们从读取行中提取恰好n个字符,并将它们复制到该行中。
之后赋值就完成了。您所需要做的就是比较map中的每个元素是否大于调整后的元素。
#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
代码中的一些问题:
- 在问题中提供的输入内容中,数字是在一个
int
类型变量表示的范围内,但是提供的链接所引用的文件中数字的内容远远超出了c++中任何整数类型的范围。您需要能够存储多达100位数字。这是你的问题的主要原因,它是每一行的数字。您可以将其视为std::string
来解决。 - 根据问题描述,需要检查上下相邻单元格。
- 使用
std::vector
代替C array
。不需要浪费未使用的内存(顺便说一下,在问题的声明中,他们说行数将在1到100之间,你可以将values
和digits
变量声明为该长度),向量自动管理它们的内存(在需要时增长),它们检查超出界限的索引等… - 使用
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;
}
- 递归求和任务的错误答案
- 为什么我在代码厨师的 CMPRSS 问题中得到 WA(错误答案)?
- 请找出我的代码中的错误,它在提交得到错误答案的同时仍然适用于我的所有测试用例
- 寻找最小楼梯成本的动态规划问题的错误答案
- 为什么可变大小的数组会导致Codechef出现错误答案
- 如何修复此代码对几个测试用例的错误答案?
- 使用幂函数的计算给出了大数字的错误答案
- 快速排序算法,一些特定输入序列的错误答案和分段错误
- 二分法程序的错误答案(C++)
- 无法理解绘图程序中的错误答案
- C++ - 整数除以整数返回错误答案
- 布尔函数的错误答案
- SPOJ FASTFLOW上的错误答案
- 代码的错误答案是在Java Camel案件和C 下划线标识符之间转换的错误答案
- 200万以下所有素数的总和,线程给出错误答案
- 0-1整数背包返回错误答案(动态编程)
- UVa 在线判断 - 3n + 1 - 错误答案
- 提升C++原始算法错误答案
- 二项式系数函数C++错误答案 n>13
- 需要帮助以避免 SPOJ 上的"错误答案"