Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

หา Sub-matrix ที่มีผลรวมเท่ากับค่าที่กำหนดใน C++

ในปัญหานี้ เราได้รับเมทริกซ์ 2D ขนาด N×N และตัวแปร sum และ size งานของเราคือ การหา sub-matrix ที่มีผลรวมเท่ากับค่าที่กำหนด

เราต้องหา sub-matrix ขนาด size×size ที่ผลรวมของสมาชิกเท่ากับ sum

ตัวอย่างเพื่อความเข้าใจ

Input : mat[][] = { {1, 5, 7, 9}
                    {2, 4, 6, 8}
                    {1, 2, 5, 6}
                    {3, 6, 9, 3} }
       sum = 22, Size = 2
Output : YES

คำอธิบาย

Submatrix ขนาด 2×2 ที่มีผลรวม 22 คือ:
{5, 7}
{4, 6}

แนวทางแก้ปัญหา

วิธีง่ายคือสร้าง submatrix ขนาด size×size ทุกตัวที่เป็นไปได้ หาผลรวมแล้วเปรียบเทียบ

วิธีที่มีประสิทธิภาพกว่า: ใช้ Dynamic Programming สร้าง DP array ที่ DP[i][j] เก็บผลรวมของสมาชิกจากแถว 0 ถึง i และคอลัมน์ 0 ถึง j จากนั้นคำนวณผลรวมของ submatrix ใดๆ ได้ใน O(1) โดยสูตร:

$$\mathrm{sum((i_s,j_s) \text{ to } (i_e,j_e)) = DP[i_e][j_e] + DP[i_s-1][j_s-1] - DP[i_s-1][j_e] - DP[i_e][j_s-1]}$$

อัลกอริทึม

  • ขั้นตอนที่ 1 − สร้าง DP matrix ขนาด (n+1)×(n+1)
  • ขั้นตอนที่ 2 − สำหรับแต่ละสมาชิก หาผลรวมสะสมจนถึงดัชนีนั้น
  • ขั้นตอนที่ 3 − สำหรับทุกดัชนี หาผลรวม submatrix ขนาด size×size ด้วยสูตรด้านบน
  • ขั้นตอนที่ 4 − หาก currSum == sum ให้คืนค่า true
  • ขั้นตอนที่ 5 − คืนค่า false

ตัวอย่างโค้ด

#include <iostream>
using namespace std;

#define N 4

bool findSubMatWithSum(int size, int sum, int mat[N][N]) {
    int DP[N + 1][N + 1];
    
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            DP[i + 1][j + 1] = DP[i + 1][j] + DP[i][j + 1] - DP[i][j] + mat[i][j];
    
    int currSum = 0;
    for (int i = 0; i <= N - size; i++)
        for (int j = 0; j <= N - size; j++) {
            currSum = DP[i][j] + DP[i + size][j + size] - DP[i + size][j] - DP[i][j + size];
            if (currSum == sum)
                return true;
        }
    return false;
}

int main() {
    int mat[N][N] = { { 1, 5, 7, 9 },
                      { 2, 4, 6, 8 },
                      { 1, 2, 5, 6 },
                      { 3, 6, 9, 3 } };
    int size = 2;
    int sum = 22;
    
    if (findSubMatWithSum(size, sum, mat))
        cout << "Sub-Matrix of given size having the given sum is possible!";
    else
        cout << "Sub-Matrix of given size having the given sum is not possible!";
    
    return 0;
}

ผลลัพธ์

Sub-Matrix of given size having the given sum is possible!