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
我的c ++代码:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream fd ("file.txt"); // this file contains the grid
int A[463],max=-1;
for (int i=1;i<=400;i++){
fd >> A[i];
}
for (int i=463;i>400;i--){ // zero out array numbers that exceed 400
A[i]=0;
}
for (int i=1;i<=400;i++){
if ((A[i]*A[i+20]*A[i+40]*A[i+60])>max){ //vertical maximum
max=A[i]*A[i+20]*A[i+40]*A[i+60];
}
if ((i%20!=0)||((i-18)%20!=0)||((i-19)%20!=0)){ //diagnol \ maximum (first if checks if out of bounds)
if ((A[i]*A[i+21]*A[i+42]*A[i+63])>max){
max=A[i]*A[i+21]*A[i+42]*A[i+63];
}
}
if (((i-1)%20!=0)||((i-2)%20!=0)||((i-3)%20!=0)){// diagnol / maximum (first if checks if out of bounds)
if ((A[i]*A[i+19]*A[i+18]*A[i+17])>max){
max=A[i]*A[i+19]*A[i+18]*A[i+17];
}
}
if ((i+2)%20!=0){ // horizontal maximum (first if checks if out of bounds)
if ((A[i]*A[i+1]*A[i+2]*A[i+3])>max){
max=A[i]*A[i+1]*A[i+2]*A[i+3];
}
}
}
cout <<max;
fd.close();
return 0;
}
使用此代码,我得到答案51267216,这是垂直答案,但这个答案不正确,我认为我的诊断检查有问题。 如果我输出诊断最大值,我会得到一些接近最大垂直但不正确的4xxxxxxx。 P.S我检查/和\ diagnols。
答案 0 :(得分:0)
事实上,对角线的测试看起来是错误的。 例如,\对角线测试应该是:
// not starting from the 3 rightmost columns,
// not starting from the 3 bottom rows
if ((i%20 <= 16) && i < 20*17)
另一个对角线应为:
// idem above:
if ((i%20 >= 3) && i < 20*17)
修改:
右上角到左下角的索引是错误的:它们应该是{0,19,2 * 19,3 * 19},即{0,19,38,57}:
这是整个for循环,输出正确的结果:(70600674)
for (int i=0; i < 400; ++i) // <- I used a regular array indexed from 0
{
if (i < 17 * 20)
{
if ((A[i] * A[i + 20] * A[i + 40] * A[i + 60]) > max)
{
max = A[i] * A[i + 20] * A[i + 40] * A[i + 60];
}
if (i % 20 <= 16)
{
if ((A[i] * A[i + 21] * A[i + 42] * A[i + 63]) > max)
{
max = A[i] * A[i + 21] * A[i + 42] * A[i + 63];
}
}
if (i % 20 >= 3)
{
if ((A[i] * A[i + 19] * A[i + 38] * A[i + 57]) > max)
{
max = A[i] * A[i + 19] * A[i + 38] * A[i + 57];
}
}
}
if (i % 20 <= 16)
{
if ((A[i]*A[i+1]*A[i+2]*A[i+3])>max)
{
max=A[i]*A[i+1]*A[i+2]*A[i+3];
}
}
}
在旁注中,二维数组会更清晰(你可能不会犯这样的错误)
答案 1 :(得分:0)
您应该做的第一件事是使用2D阵列。它们使您的问题看起来更容易。第二件事 - 使用常量。不要使用无意义的数字,这些数字看起来像黑魔法的第二个人。第三件事 - 使用三行三列的右,左,下填充。最后要记住的事情 - 像其他人一样阅读你的代码。即使只有你和一台电脑会看到代码 - 这是一个好习惯,并在你申请工作时给你一个进步。
const int parameters = 20;
const int padding = 3;
int tab[parameters + padding][parameters + padding];
请参阅?它更容易阅读并告诉你你在做什么。额外的列和行将为我们提供大量if if
语句。您可以将程序打包到函数中 - 它更易于阅读和使用。通常我会通过定义一个新类来实现,但出于算法目的,我将使用全局变量和函数。
#include <fstream>
using namespace std;
const int parameters = 20;
const int padding = 3;
int tab[parameters + padding][parameters + 2*padding];
int diagonalLeft(int i, int j) {
int answer = 1;
for (int u = 0; u <= padding; u++)
answer *= tab[i - u][j - u];
return answer;
}
int diagonalRight(int i, int j) {
int answer = 1;
for (int u = 0; u <= padding; u++)
answer *= tab[i - u][j + u];
return answer;
}
int vertical(int i, int j) {
int answer = 1;
for (int u = 0; u <= padding; u++)
answer *= tab[i + u][j];
return answer;
}
int horizontal(int i, int j){
int answer = 1;
for (int u = 0; u <= padding; u++)
answer *= tab[i][j + u];
return answer;
}
int max(int a, int b) {
if (a > b)
return a;
return b;
}
int main() {
ifstream input("file.txt");
for (int i = 0; i < parameters; i++)
for (int j = padding; j < parameters + padding; j++)
input >> tab[i][j];
int maximum = 0;
int temp;
for (int i = 0; i < parameters; i++) {
for (int j = padding; j < parameters + padding; j++) {
temp = diagonalLeft(i, j);
temp = max(temp, diagonalRight(i, j));
temp = max(temp, vertical(i, j));
temp = max(temp, horizontal(i, j));
maximum = max(maximum, temp);
}
}
cout << maximum << endl;
input.close();
return 0;
}
如果您的代码不仅更容易阅读,更容易在干净的代码中找到错误。甚至不要试图在你的代码中找到它们,因为它甚至需要几个小时。
发明二维阵列是有原因的。由于这个一维数组,你可能会有比你想象的更多的错误。
查看if
语句的大小。我的更短,更容易调试。桌子周围的填充物让我没有例外,就像你拥有的那样。