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 any direction (up, down, left, right, or diagonally) in the 20×20 grid?
求这20*20矩阵里面相邻的四个数,最大的乘积。
相邻包括,上下,左右,对角这些位置。
思路:
一,将字符串转换为对应的二维的整形数组。
二,对于二维数组里面的每个一个点,求解这几个方向关联的四个值。
以这个点为起点的四个方向(注意这里用四个方向,而不是8个方向,可以避免重复计算。)
右上对角
右下对角
右边
下面
如果其中任何一边不足4个元素(包括这个点本身),就以0为值。
比较这4个值里面最大的值。
这样对应于每个点,都存在这样一个值。
三,遍历二维数组,比较各个点最大值的最大值。也就是矩阵的最大值了。
里面有几个需要注意的地方:
一,如何将这个字符串转换为对应二维数组。
二,如何求解对应每个点的最大值。
三,要求了解多维数组的参数传递。
欧拉项目第十一题#include <stdio.h> #include <stdlib.h> // 分析矩阵中每个点带动的周围的四个方向的乘积的最大值 // 四个方向分别为 右上对角线, 向右, 右下对角线, 向下 // 参数 i, j 分别为对应坐标 , 返回值为 i, j 坐标对应的四个方向里面的最大值 unsigned long pointMax(int (*arr)[], int i, int j); int main(int argc, char *argv[]) { char *p = "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"; int arr[20][20]; int row = 0, col = 1; // 将字符串转换到整形数组中 while(*p != '\0') { if(col % 21 != 0) { arr[row][col - 1] = (*p - 48) * 10 + *(p + 1) - 48; col ++; if((row == 19) && (col == 21)) { break; } else p += 3; } else { row++; col = 1; } } int showrow = 0, showcol = 0; // 显示二维数组 for(showrow = 0; showrow < 20; showrow ++) for(showcol = 1; showcol < 21; showcol++) { printf("%3d", arr[showrow][showcol - 1]); if(showcol % 20 == 0) printf("\n"); } unsigned long max = 0; row = 0, col = 0; for(row = 0 ; row < 20; row++) for(col = 0; col < 20; col++) { unsigned long tmp = pointMax(arr, row, col); if(tmp > max) max = tmp; } printf("%lu\n", max); system("PAUSE"); return 0; } unsigned long pointMax(int (*arr)[20], int i, int j) { unsigned long maxArr[4]; // 临时数组存放来自4个方向的值 unsigned long max = 0; if(i >= 3 && j <= 16) // 判断右上角的3个元素是不是都存在 { maxArr[0] = arr[i - 1][j + 1] * arr[i - 2][j + 2] * arr[i - 3][j + 3] * arr[i][j]; } else { maxArr[0] = 0; } if(j <= 16) // 判断右边的3个元素 { maxArr[1] = arr[i][j] * arr[i][j + 1] * arr[i][j + 2] * arr[i][j + 3]; } else { maxArr[1] = 0; } if(i <= 16 && j <= 16) // 判断右下角的3个元素 { maxArr[2] = arr[i + 1][j + 1] * arr[i + 2][j + 2] * arr[i + 3][j + 3] * arr[i][j]; } else { maxArr[2] = 0; } if(i <= 16) // 判断下方的3个元素 { maxArr[3] = arr[i + 1][j] * arr[i + 2][j] * arr[i + 3][j] * arr[i][j]; } else { maxArr[3] = 0; } int k; for(k = 0; k <4; k++) { if(maxArr[k] > max) max = maxArr[k]; } return max; }