Крупнейший продукт в сетке «Не в том же направлении»

https://projecteuler.net/problem=11 Вот вопрос:

int grid[20][20] = 
    {
        {8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8},
        {49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0},
        {81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65},
        {52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 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, 3, 45, 2, 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, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21},
        {24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72},
        {21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95},
        {78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92},
        {16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57},
        {86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58},
        {19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40},
        {4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66},
        {88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69},
        {4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36},
        {20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16},
        {20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54},
        {1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48}
    };

Каково наибольшее произведение четырех соседних чисел в «одном направлении» (вверх, вниз, влево, вправо или по диагонали) в сетке 20 на 20? Сначала я неправильно прочитал вопрос и не увидел части «в том же направлении». Я думал, что правило заключается в том, что каждое число должно быть соседним хотя бы с одним другим числом в сетке, а не максимум.

Мне удалось решить эту проблему довольно быстро (я также использовал

Решение:

#include <stdio.h>

// Function to find the maximum product of four adjacent numbers in a grid
int findMaxProduct(int grid[20][20], int* pos)
{
    int maxProduct = 0;

    // Check horizontally
    for (int i = 0; i < 20; i++)
    {
        for (int j = 0; j < 20 - 3; j++)
        {
            int product = grid[i][j] * grid[i][j + 1] * grid[i][j + 2] * grid[i][j + 3];
            printf("Checking horizontally at (%d, %d) -> product: %d\n", i, j, product);
            if (product > maxProduct)
            {
                maxProduct = product;
                pos[0] = i; pos[1] = j;
                pos[2] = i; pos[3] = j + 1;
                pos[4] = i; pos[5] = j + 2;
                pos[6] = i; pos[7] = j + 3;
                printf("New max horizontal product found: %d at (%d, %d), (%d, %d), (%d, %d), (%d, %d)\n",
                       maxProduct, pos[0], pos[1], pos[2], pos[3], pos[4], pos[5], pos[6], pos[7]);
            }
        }
    }

    // Check vertically
    for (int i = 0; i < 20 - 3; i++)
    {
        for (int j = 0; j < 20; j++)
        {
            int product = grid[i][j] * grid[i + 1][j] * grid[i + 2][j] * grid[i + 3][j];
            printf("Checking vertically at (%d, %d) -> product: %d\n", i, j, product);
            if (product > maxProduct)
            {
                maxProduct = product;
                pos[0] = i; pos[1] = j;
                pos[2] = i + 1; pos[3] = j;
                pos[4] = i + 2; pos[5] = j;
                pos[6] = i + 3; pos[7] = j;
                printf("New max vertical product found: %d at (%d, %d), (%d, %d), (%d, %d), (%d, %d)\n",
                       maxProduct, pos[0], pos[1], pos[2], pos[3], pos[4], pos[5], pos[6], pos[7]);
            }
        }
    }

    // Check diagonally (down-right)
    for (int i = 0; i < 20 - 3; i++)
    {
        for (int j = 0; j < 20 - 3; j++)
        {
            int product = grid[i][j] * grid[i + 1][j + 1] * grid[i + 2][j + 2] * grid[i + 3][j + 3];
            printf("Checking diagonally down-right at (%d, %d) -> product: %d\n", i, j, product);
            if (product > maxProduct)
            {
                maxProduct = product;
                pos[0] = i; pos[1] = j;
                pos[2] = i + 1; pos[3] = j + 1;
                pos[4] = i + 2; pos[5] = j + 2;
                pos[6] = i + 3; pos[7] = j + 3;
                printf("New max diagonal down-right product found: %d at (%d, %d), (%d, %d), (%d, %d), (%d, %d)\n",
                       maxProduct, pos[0], pos[1], pos[2], pos[3], pos[4], pos[5], pos[6], pos[7]);
            }
        }
    }

    // Check diagonally (down-left)
    for (int i = 0; i < 20 - 3; i++)
    {
        for (int j = 3; j < 20; j++)
        {
            int product = grid[i][j] * grid[i + 1][j - 1] * grid[i + 2][j - 2] * grid[i + 3][j - 3];
            printf("Checking diagonally down-left at (%d, %d) -> product: %d\n", i, j, product);
            if (product > maxProduct)
            {
                maxProduct = product;
                pos[0] = i; pos[1] = j;
                pos[2] = i + 1; pos[3] = j - 1;
                pos[4] = i + 2; pos[5] = j - 2;
                pos[6] = i + 3; pos[7] = j - 3;
                printf("New max diagonal down-left product found: %d at (%d, %d), (%d, %d), (%d, %d), (%d, %d)\n",
                       maxProduct, pos[0], pos[1], pos[2], pos[3], pos[4], pos[5], pos[6], pos[7]);
            }
        }
    }

    return maxProduct;
}

int main(void)
{
    int grid[20][20] = 
    {
        {8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8},
        {49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0},
        {81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65},
        {52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 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, 3, 45, 2, 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, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21},
        {24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72},
        {21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95},
        {78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92},
        {16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57},
        {86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58},
        {19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40},
        {4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66},
        {88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69},
        {4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36},
        {20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16},
        {20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54},
        {1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48}
    };

    int pos[8]; // To store the positions of the 4 adjacent numbers with the highest product
    int maxProduct = findMaxProduct(grid, pos);

    printf("The maximum product of four adjacent numbers is %d.\n", maxProduct);
    printf("The positions of these numbers are:\n");
    for (int i = 0; i < 8; i += 2)
    {
        printf("(%d, %d)\n", pos[i], pos[i + 1]);
    }

    return 0;
}

Что, если мы рассмотрим числа, расположенные в разных направлениях? Единственное правило заключается в том, что каждое число должно быть смежным хотя бы с одним другим числом, а не только с одним другим числом. Как будто сам ответ может состоять из 4 чисел, которые примыкают друг к другу, как квадратная матрица 2 на 2?

Теперь нам предстоит искать гораздо больше вещей. Поиск фигур в Python вручную

def is_in_bounds(x, y, rows, cols):
    return 0 <= x < rows and 0 <= y < cols

def generate_combinations(x, y):
    return 
    [
        [(x, y), (x+1, y), (x+2, y), (x+3, y)],  # Horizontal line
        [(x, y), (x, y+1), (x, y+2), (x, y+3)],  # Vertical line
        [(x, y), (x+1, y+1), (x+2, y+2), (x+3, y+3)],  # Diagonal down-right
        [(x, y), (x-1, y+1), (x-2, y+2), (x-3, y+3)],  # Diagonal down-left
        [(x, y), (x+1, y), (x, y+1), (x+1, y+1)],  # 2x2 square
        [(x, y), (x+1, y), (x+2, y), (x+2, y+1)],  # L-shape 1
        [(x, y), (x, y+1), (x, y+2), (x+1, y+2)],  # L-shape 2
        [(x, y), (x+1, y), (x+2, y), (x, y+1)],  # L-shape 3
        [(x, y), (x, y+1), (x, y+2), (x+1, y)],  # L-shape 4
        [(x, y), (x+1, y), (x+2, y), (x+1, y+1)],  # T-shape 1
        [(x, y), (x, y+1), (x, y+2), (x+1, y+1)],  # T-shape 2
        [(x, y), (x+1, y), (x+1, y+1), (x+1, y+2)],  # T-shape 3
        [(x, y), (x, y+1), (x-1, y+1), (x+1, y+1)]  # T-shape 4
    ]

def calculate_product(grid, combination):
    product = 1
    for x, y in combination:
        product *= grid[x][y]
    return product

def find_max_product(grid):
    max_product = 0
    max_combination = []
    rows = len(grid)
    cols = len(grid[0])
    
    for i in range(rows):
        for j in range(cols):
            combinations = generate_combinations(i, j)
            valid_combinations = [comb for comb in combinations if all(is_in_bounds(x, y, rows, cols) for x, y in comb)]
            
            for comb in valid_combinations:
                product = calculate_product(grid, comb)
                print(f"Combination: {comb} => Values: {[grid[x][y] for x, y in comb]} => Product: {product}")
                
                if product > max_product:
                    max_product = product
                    max_combination = comb
    
    print(f"Max product combination: {max_combination} => Product: {max_product}")
    return max_product

# Example usage
grid = [[int(x) for x in line.split()] for line in """
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
""".strip().split('\n')]

print(find_max_product(grid))

Но если задача требует n=5; Мне нужно будет вручную найти больше фигур на ручке и бумаге. Есть ли другой способ найти все возможные комбинации чисел «n» (где хотя бы одно число соседствует с другим). Есть ли у нас формула для этого? куда я подключаю, и он сообщает мне, сколько существует возможных фигур?

Общая идея такова: все возможные фигуры с 5 — это все возможные фигуры с 4, к которым вы добавляете 1 — и вам следует удалить дубликаты.

Thierry Lathuille 19.08.2024 13:14

Разрешаете ли вы использовать номер более одного раза?

MrSmith42 19.08.2024 13:35

Справедливости ради, если мы считаем две ячейки по диагонали соседними, generate_combinations все равно не хватает множества возможных комбинаций. Если рассматривать только горизонтально-вертикальное соседство, то все возможные комбинации из 4 клеток на самом деле напоминают 19 фигурок тетриса (Тетромино).

Rexy 19.08.2024 14:06

Ох, попробую исправить.

KungFuPanda 19.08.2024 14:33
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Учитывая любую связанную фигуру из n плиток, вы можете:

  1. Найдите плитки с наименьшей координатой y и выберите одну из плиток с наименьшей координатой x. Это «стартовая плитка»
  2. Пройдите оставшиеся плитки, используя BFS. Рассматривая соседние ячейки каждой плитки, отслеживайте, какие из них вы изучаете, отмечайте их seen и исследуйте только те ячейки, которые вы раньше не видели.
  3. Когда вы изучаете новую (невидимую) ячейку:
    1. Если в ячейке есть плитка, выведите 1 и добавьте плитку в очередь BFS;
    2. В противном случае напишите 0.

Эта процедура создаст уникальный двоичный код для каждой плитки.

Если вы хотите найти все возможные плитки, вы можете использовать процедуру рекурсивного поиска с возвратом, которая находит все фигуры, соответствующие возможным результатам этой процедуры:

# generate all shapes with n tiles
def genTiles(n):
    if (n<1):
        return []

    alldirs=[]
    # generate a list of all directions
    for x in range(-1,2):
        for y in range(-1,2):
            if x!=0 or y!=0:
                alldirs.append((x,y))

    # we'll collect all the outputs here
    ret=[]
    # BFS q
    q = [(0,0)]
    # cells we've seen
    seen = dict()
    seen[(0,0)] = True
    def expand(qpos, nleft, index):
        if nleft < 1:
            ret.append(q[:])
            return
        # find the next unseen cell
        index -= 1
        while True:
            index += 1
            if index >= len(alldirs):
                qpos += 1
                index = 0
                if qpos >= len(q):
                    return
            test = (
                q[qpos][0] + alldirs[index][0],
                q[qpos][1] + alldirs[index][1]
            )
            if test[1] < 0 or (test[1] == 0 and test[0] <= 0):
                continue
            if seen.get(test) != True:
                break
        seen[test] = True
        # choose
        q.append(test)
        expand(qpos, nleft-1, index+1)
        # unchoose
        q.pop()
        expand(qpos, nleft, index+1)
        seen[test] = False
    expand(0,n-1,0)
    return ret

Добавьте этот тест, чтобы распечатать все 110 фигур с 4 плитками.

# test
N = 4
shapes = genTiles(N)
print("there are {0} shapes with {1} tiles:".format(len(shapes), N))
for tile in shapes:
    print(tile)

Как видите, разрешение диагональных соединений добавляет массу возможностей. Даже на 3 плитки приходится 20 фигур:

there are 20 shapes with 3 tiles:
[(0, 0), (-1, 1), (0, 1)]
[(0, 0), (-1, 1), (1, 0)]
[(0, 0), (-1, 1), (1, 1)]
[(0, 0), (-1, 1), (-2, 1)]
[(0, 0), (-1, 1), (-2, 2)]
[(0, 0), (-1, 1), (-1, 2)]
[(0, 0), (-1, 1), (0, 2)]
[(0, 0), (0, 1), (1, 0)]
[(0, 0), (0, 1), (1, 1)]
[(0, 0), (0, 1), (-1, 2)]
[(0, 0), (0, 1), (0, 2)]
[(0, 0), (0, 1), (1, 2)]
[(0, 0), (1, 0), (1, 1)]
[(0, 0), (1, 0), (2, 0)]
[(0, 0), (1, 0), (2, 1)]
[(0, 0), (1, 1), (0, 2)]
[(0, 0), (1, 1), (1, 2)]
[(0, 0), (1, 1), (2, 0)]
[(0, 0), (1, 1), (2, 1)]
[(0, 0), (1, 1), (2, 2)]

Большое спасибо!

KungFuPanda 19.08.2024 16:09

Другие вопросы по теме