Project Euler | Problem 11

Largest product in a grid

In the 20×20 grid below, four numbers along a diagonal line have been marked in red.

08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08

49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00

81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65

52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91

22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80

24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50

32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70

67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21

24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72

21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95

78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92

16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57

86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58

19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40

04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66

88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69

04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36

20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16

20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54

01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48

The product of these numbers is  26 × 63 × 78 × 14 = 1788696.

What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20 × 20 grid?


方阵中的最大乘积

在如下的20×20方阵中,有四个呈对角线排列的数被标记为红色。

08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08

49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00

81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65

52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91

22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80

24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50

32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70

67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21

24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72

21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95

78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92

16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57

86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58

19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40

04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66

88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69

04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36

20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16

20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54

01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48

这四个数的乘积是 26 × 63 × 78 × 14 = 1788696。

在这个 20 × 20 方阵中,四个呈一直线(竖直、水平或对角线)相邻的数的乘积最大是多少?


/*
*	Program 1
* 思路:
*	1.将数据矩阵导入二维数组中
*	2.对每个数求各个方向的有效乘积,并求最大值
* 收获:
*	1.1.文档操作函数
*	1.2.数组处理,尽管没有成功
*	1.3.二维数组的形参,试图找到一种更通用的形式
* 评价:
*	优点:
*		1.逐一比较,不遗漏
*		2.从文件中读取,可存入更大的矩阵
*	缺点:
*		1.暴力计算,运算量大,有很多无效运算
*		2.数组越界处理不够严密
*/

#define _CRT_SECURE_NO_WARNINGS
#define ROW 20
#define COL 20
#define CONTINUITY 4

#include <stdio.h>

/*---------------------------------------------------------*/

//存放 txt文件中导出的数据矩阵
int matrix[ROW][COL] = { 0 };

//在连续 continuity个数条件下,二维数组 matrix中,返回第(iRow,iCol)位数据横向乘积
//注意:从(iRow,iCol)位开始,从左往右;没有越界处理;// 收获1.2
int ProductHorizon(int matrix[ROW][COL], int iRow, int iCol, int continuity)// 收获1.3
{
	int product = 1;
	while (continuity--)
	{
		product *= matrix[iRow++][iCol];
	}
	return product;
}

//在连续 continuity个数条件下,二维数组 matrix中,返回第(iRow,iCol)位数据纵向乘积
//注意:从(iRow,iCol)位开始,从上到下;没有越界处理;
int ProductVertical(int matrix[ROW][COL], int iRow, int iCol, int continuity)
{
	if ((iRow >= 0) && (iRow < ROW)
		&& (iCol >= 0) && (iCol + CONTINUITY > COL))
	{
		return 0;
	}
	int product = 1;
	while (continuity--)
	{
		product *= matrix[iRow][iCol++];
	}
	return product;
}

//在连续 continuity个数条件下,二维数组 matrix中,返回第(iRow,iCol)位数据撇向乘积
//注意:从(iRow,iCol)位开始,从左上往右下;没有越界处理;
int ProductLeftDiagonal(int matrix[ROW][COL], int iRow, int iCol, int continuity)
{
	if ((iRow + iCol >= CONTINUITY - 1) && (iRow + iCol <= ROW + COL - CONTINUITY - 1))
	{
		return 0;
	}
	int product = 1;
	while (continuity--)
	{
		product *= matrix[iRow--][iCol++];
	}
	return product;
}

//在连续 continuity个数条件下,二维数组 matrix中,返回第(iRow,iCol)位数据捺向乘积
//注意:从(iRow,iCol)位开始,从左上往右下;没有越界处理;
int ProductRightDiagonal(int matrix[ROW][COL], int iRow, int iCol, int continuity)
{
	int product = 1;
	while (continuity--)
	{
		product *= matrix[iRow++][iCol++];
	}
	return product;
}

/*------------------------------------------------------------------------*/
int main()
{
	//将 txt文件中的数字矩阵导入二维数组中
	FILE* pf = fopen("matrix.txt", "r");
	if (pf == NULL)
	{
		perror("Error:");
		return 0;
	}
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			fscanf(pf, "%d", &matrix[i][j]);// 收获1.1
		}
	}
	fclose(pf);
	pf = NULL;

	//求最大值
	int max = 0;
	int product = 0;
	int i = 0;
	int j = 0;
	//横向的乘积
	for (i = 0; i <= ROW - CONTINUITY; i++)
	{
		for (j = 0; j < COL; j++)
		{
			product = ProductHorizon(matrix, i, j, CONTINUITY);
			(max < product) ? (max = product) : (1);
		}
	}
	//纵向的乘积
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j <= COL - CONTINUITY; j++)
		{
			product = ProductVertical(matrix, i, j, CONTINUITY);
			(max < product) ? (max = product) : (1);
		}
	}
	//撇的乘积
	for (i = CONTINUITY - 1; i < ROW; i++)
	{
		for (j = 0; j <= COL - CONTINUITY; j++)
		{
			product = ProductLeftDiagonal(matrix, i, j, CONTINUITY);
			(max < product) ? (max = product) : (1);
		}
	}
	//捺的积
	for (i = 0; i <= ROW - CONTINUITY; i++)
	{
		for (j = 0; j <= COL - CONTINUITY; j++)
		{
			product = ProductRightDiagonal(matrix, i, j, CONTINUITY);
			(max < product) ? (max = product) : (1);
		}
	}

	printf("%d\n", max);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值