Thuật toán điền số vào ma trận

Bài toán – Thuật toán điền số vào ma trận

Hãy lập thuật toán điền các phần tử của ma trận N´N các số 0, 1 và -1 sao cho:

a) Tổng các số của mọi hình vuông con 2×2 đều bằng 0.

b) Tổng các số của ma trận trên là lớn nhất.

Thuật toán

Để lập thuật toán điền các phần tử của ma trận N x N các số 0, 1 và -1 sao cho tổng các số của mọi hình vuông con 2×2 đều bằng 0 và tổng các số của ma trận trên là lớn nhất, chúng ta có thể sử dụng phương pháp đặt giá trị cho mỗi phần tử của ma trận bằng cách sử dụng đệ quy.

Cụ thể, để đảm bảo điều kiện a), chúng ta có thể đặt giá trị của phần tử tại hàng i, cột j của ma trận bằng 1 hoặc -1 tuỳ theo giá trị của phần tử tại hàng i-1, cột j-1. Nếu phần tử đó bằng 1 thì phần tử tại hàng i, cột j sẽ bằng -1 và ngược lại. Nếu i=1 hoặc j=1, ta có thể đặt giá trị của phần tử đó bằng 0.

Để đảm bảo điều kiện b), chúng ta có thể tính tổng của mọi phần tử của ma trận và so sánh với giá trị lớn nhất hiện tại. Nếu tổng này lớn hơn giá trị lớn nhất hiện tại thì cập nhật giá trị lớn nhất này.

Cài đặt bài toán với Python

def fillMatrix(N):
    # Khởi tạo ma trận N x N với giá trị ban đầu là 0
    matrix = [[0 for i in range(N)] for j in range(N)]
    # Khởi tạo biến lưu giá trị lớn nhất của tổng các phần tử trong ma trận
    maxSum = 0
    
    # Hàm đệ quy fillHelper để đặt giá trị cho từng phần tử và tính tổng các phần tử
    def fillHelper(i, j, currentSum):
        nonlocal maxSum
        
        # Nếu i == N thì đã đặt giá trị cho tất cả phần tử trong ma trận
        if i == N:
            # Nếu tổng các phần tử lớn hơn giá trị lớn nhất hiện tại thì cập nhật giá trị lớn nhất
            if currentSum > maxSum:
                maxSum = currentSum
            return
        
        # Thử đặt giá trị 1 tại phần tử i, j
        matrix[i][j] = 1
        # Kiểm tra điều kiện a) bằng cách tính tổng các phần tử trong hình vuông con 2x2
        if i > 0 and j > 0:
            squareSum = matrix[i-1][j-1] + matrix[i-1][j] + matrix[i][j-1] + matrix[i][j]
            # Nếu tổng khác 0 thì không đặt giá trị 1 tại phần tử i, j
            if squareSum != 0:
                matrix[i][j] = -1
        # Đệ quy tiếp tục đặt giá trị cho phần tử tiếp theo
        fillHelper(i + (j + 1) // N, (j + 1) % N, currentSum + matrix[i][j])
        
        # Thử đặt giá trị -1 tại phần tử i, j
        matrix[i][j] = -1
        # Kiểm tra điều kiện a) bằng cách tính tổng các phần tử trong hình vuông con 2x2
        if i > 0 and j > 0:
            squareSum = matrix[i-1][j-1] + matrix[i-1][j] + matrix[i][j-1] + matrix[i][j]
            # Nếu tổng khác 0 thì không đặt giá trị -1 tại phần tử i, j
            if squareSum != 0:
                matrix[i][j] = 1
        # Đệ quy tiếp tục đặt giá trị cho phần tử tiếp theo
        fillHelper(i + (j + 1) // N, (j + 1) % N, currentSum + matrix[i][j])
        
       # Reset giá trị của phần tử
        matrix[i][j] = 0
    
    # Gọi hàm đệ quy fillHelper với i = 0, j = 0 và currentSum = 0 để điền giá trị cho ma trận
    fillHelper(0, 0, 0)
    # Trả về giá trị lớn nhất của tổng các phần tử trong ma trận
    return maxSum

Cài đặt bài toán bằng C++

#include <iostream>
using namespace std;

const int N = 4;

int matrix[N][N];
int maxSum = 0;

void fillHelper(int i, int j, int currentSum) {
    // Nếu i == N thì đã đặt giá trị cho tất cả phần tử trong ma trận
    if (i == N) {
        // Nếu tổng các phần tử lớn hơn giá trị lớn nhất hiện tại thì cập nhật giá trị lớn nhất
        if (currentSum > maxSum) {
            maxSum = currentSum;
        }
        return;
    }
    
    // Thử đặt giá trị 1 tại phần tử i, j
    matrix[i][j] = 1;
    // Kiểm tra điều kiện a) bằng cách tính tổng các phần tử trong hình vuông con 2x2
    if (i > 0 && j > 0) {
        int squareSum = matrix[i-1][j-1] + matrix[i-1][j] + matrix[i][j-1] + matrix[i][j];
        // Nếu tổng khác 0 thì không đặt giá trị 1 tại phần tử i, j
        if (squareSum != 0) {
            matrix[i][j] = -1;
        }
    }
    // Đệ quy tiếp tục đặt giá trị cho phần tử tiếp theo
    fillHelper(i + (j + 1) / N, (j + 1) % N, currentSum + matrix[i][j]);
    
    // Thử đặt giá trị -1 tại phần tử i, j
    matrix[i][j] = -1;
    // Kiểm tra điều kiện a) bằng cách tính tổng các phần tử trong hình vuông con 2x2
    if (i > 0 && j > 0) {
        int squareSum = matrix[i-1][j-1] + matrix[i-1][j] + matrix[i][j-1] + matrix[i][j];
        // Nếu tổng khác 0 thì không đặt giá trị -1 tại phần tử i, j
        if (squareSum != 0) {
            matrix[i][j] = 1;
        }
    }
    // Đệ quy tiếp tục đặt giá trị cho phần tử tiếp theo
    fillHelper(i + (j + 1) / N, (j + 1) % N, currentSum + matrix[i][j]);
    
    // Reset giá trị của phần tử
    matrix[i][j] = 0;
}

int fillMatrix() {
    // Khởi tạo giá trị ban đầu cho ma trận là 0
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            matrix[i][j] = 0;
        }
    }
    fillHelper(0, 0, 0);
    return maxSum;
}

int main() {
    cout << fillMatrix() << endl;
    return 0;
}

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *