给出一个6x6 2D阵列,:
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
在此图形表示形式中,我们将沙漏定义为值的子集,其中索引按此模式落入
a b c
d
e f g
arr中有16个沙漏,沙漏和是沙漏值的总和。计算以arr为单位的每个沙漏的沙漏总和,然后打印最大沙漏总和。
例如,给定2D数组:
-9 -9 -9 1 1 1
0 -9 0 4 3 2
-9 -9 -9 1 2 3
0 0 8 6 6 0
0 0 0 -2 0 0
0 0 1 2 4 0
我们计算以下16个沙漏值:
-63, -34, -9, 12,
-10, 0, 28, 23,
-27, -11, -2, 10,
9, 17, 25, 18
这是我编写的代码
#include<stdio.h>
const int M=6;
const int N=6;
int hourglassSum(int arr_rows, int arr_columns, int arr[M][N]) {
int rows,columns;
rows=arr_rows-(arr_rows/3);
columns=arr_columns-(arr_columns/3);
int a[columns-1][rows-1];
int min_r,min_c,max_r,max_c,sum;
sum=0;
for(int k=0;k<columns;k++)
{
min_c=k;
max_c=k+2;
for(int l=0;l<rows;l++)
{
min_r=l;
max_r=l+2;
sum=0;
for(int i=min_c;i<=max_c;i++)
{
if(max_c>=arr_columns)
break;
for(int j=min_r;j<=max_r;j++)
{
if(max_r>=arr_rows)
break;
if(i!=min_c && i!=max_c)
{
int no=j+1;
sum +=arr[i][no];
break;
}
sum += arr[i][j];
}
}
a[min_c][min_r]=sum;
}
}
int max=-111;
for(int b=0;b<columns;b++)
{
for(int c=0;c<rows;c++)
{
if(max<a[b][c])
max=a[b][c];
}
}
for(int i=0;i<columns;i++)
{
for(int j=0;j<rows;j++)
printf("%d ",a[i][j]);
printf("\n");
}
return max;
}
int main()
{
int arr[6][6];
int arr_rows=6;
int arr_columns=6;
for(int i=0;i<arr_columns;i++)
for(int j=0;j<arr_rows;j++)
scanf("%d",&arr[i][j]);
int result=hourglassSum(arr_rows,arr_columns,arr);
printf("\n%d",result);
}
我输入为
-9 -9 -9 1 1 1
0 -9 0 4 3 2
-9 -9 -9 1 2 3
0 0 8 6 6 0
0 0 0 -2 0 0
0 0 1 2 4 0
预期输出为
-63 -34 -9 12
-10 0 28 23
-27 -11 -2 10
9 17 25 18
但我的输出是
-63 -34 -9 -10
-10 0 28 -27
-27 -11 -2 9
9 17 25 18
怎么了?
答案 0 :(得分:0)
要输出最大和,不需要创建辅助数组。您所需要做的就是正确计算两个嵌套循环的迭代次数。
在您的函数中,这些计算和数组的声明
rows=arr_rows-(arr_rows/3);
columns=arr_columns-(arr_columns/3);
int a[columns-1][rows-1];
不正确。例如,不清楚为什么数组的行数等于columns - 1
的值。
该函数可以更简单地编写。
您在这里。
#include <stdio.h>
enum { M = 6, N = 6 };
long long int hourglassSum( int ( *a )[N], size_t m )
{
long long int max_sum = 0;
const size_t SIZE = 3;
if ( !( m < SIZE ) )
{
max_sum = ( long long int )
a[0][0] + a[0][1] + a[0][2] +
a[1][1] +
a[2][0] + a[2][1] + a[2][2];
for ( size_t i = 0; i + SIZE - 1 < m; i++ )
{
for ( size_t j = i == 0 ? 1 : 0; j + SIZE - 1 < N; j++ )
{
long long int sum = ( long long int )
a[i][j] + a[i][j+1] + a[i][j+2] +
a[i+1][j+1] +
a[i+2][j] + a[i+2][j+1] + a[i+2][j+2];
// printf( "%lld\n", sum );
if ( max_sum < sum ) max_sum = sum;
}
}
}
return max_sum;
}
int main(void)
{
int a[M][N] =
{
{ -9, -9, -9, 1, 1, 1 },
{ 0, -9, 0, 4, 3, 2 },
{ -9, -9, -9, 1, 2, 3 },
{ 0, 0, 8, 6, 6, 0 },
{ 0, 0, 0, -2, 0, 0 },
{ 0, 0, 1, 2, 4, 0 }
};
long long int sum = hourglassSum( a, M );
printf( "Hourglass Sum = %lld\n", sum );
return 0;
}
程序输出为
Hourglass Sum = 28
答案 1 :(得分:0)
您的计算:
rows=arr_rows-(arr_rows/3);
columns=arr_columns-(arr_columns/3);
因为6 / 3
为2,所以会产生正确的答案,这是要减去的正确值。如果矩阵为12x12,则将省略行和列-由于沙漏的形状,您应减去2(对于非正方形的一般情况,应减去hourglass_width - 1
和hourglass_height - 1
沙漏)。
使用int max=-111;
是危险的-再次,它碰巧适用于示例数据,但这不是一般的解决方案。使用a[0][0]
中的值作为初始最大值。这可能是一个幸运的猜测,实际上是最大值,但是如果有一个最大值,它将被另一个较大的值代替。
您应消除M
和N
并使用:
int hourglassSum(int arr_rows, int arr_columns, int arr[arr_rows][arr_columns]) {
这将允许您将其他大小的数组传递给代码。
但是,主要问题是使a
矩阵太小。
您应该使用int a[columns][rows]
。 (C语言中的数组通常为a[rows][columns]
,但是如果您保持一致,则可以将它们取反,无论如何,rows == columns
的区别都无关紧要。)使用小尺寸矩阵,我得到的结果是;使用正确大小的矩阵,我得到了预期的结果。
#include <stdio.h>
static int hourglassSum(int arr_rows, int arr_columns, int arr[arr_rows][arr_columns])
{
int rows = arr_rows - 2;
int columns = arr_columns - 2;
int a[columns][rows];
for (int k = 0; k < columns; k++)
{
int min_c = k;
int max_c = k + 2;
for (int l = 0; l < rows; l++)
{
int min_r = l;
int max_r = l + 2;
int sum = 0;
for (int i = min_c; i <= max_c; i++)
{
if (max_c >= arr_columns)
break;
for (int j = min_r; j <= max_r; j++)
{
if (max_r >= arr_rows)
break;
if (i != min_c && i != max_c)
{
int no = j + 1;
sum += arr[i][no];
break;
}
sum += arr[i][j];
}
}
a[k][l] = sum;
}
}
int max = a[0][0];
for (int b = 0; b < columns; b++)
{
for (int c = 0; c < rows; c++)
{
if (max < a[b][c])
max = a[b][c];
}
}
for (int i = 0; i < columns; i++)
{
for (int j = 0; j < rows; j++)
printf(" %3d", a[i][j]);
printf("\n");
}
return max;
}
int main(void)
{
int arr[6][6];
int arr_rows = 6;
int arr_columns = 6;
for (int i = 0; i < arr_columns; i++)
{
for (int j = 0; j < arr_rows; j++)
{
if (scanf("%d", &arr[i][j]) != 1)
{
fprintf(stderr, "failed to read an integer\n");
return 1;
}
}
}
int result = hourglassSum(arr_rows, arr_columns, arr);
printf("\n%d\n", result);
return 0;
}
输出:
-63 -34 -9 12
-10 0 28 23
-27 -11 -2 10
9 17 25 18
28
请注意,这几乎是问题代码的最小修正。我自己的代码在很多方面都看起来有所不同(不同的变量名称,更多的函数等)。
另一项更改(上面没有做过):实际上不需要数组a
;您可以在计算每个位置的沙漏总和后简单地记录当前的最大值。
-1 1 -1 0 0 0
0 -1 0 0 0 0
-1 -1 -1 0 0 0
0 -9 2 -4 -4 0
-7 0 0 -2 0 0
0 0 -1 -2 -4 0
我得到输出:
-5 -2 -2 0
-9 -13 -6 -8
-19 -2 -7 -6
-8 -14 -15 -14
0
这将产生您所期望的答案0
(我同意0
是应有的答案)。