0965303260
TP. Hồ Chí Minh

[C]. Các Dạng Bài Tập Mảng 2 Chiều

Bài viết này mình sẽ hướng dẫn các bạn những bài toán thường gặp trên mảng 2 chiều

NỘI DUNG : 

  • Bài Toán Liệt Kê
  • Bài Toán Xét Hàng, Cột 
  • Hoán Vị Hàng, Cột
  • Sắp Xếp Ma Trận Theo Hàng, Cột
  • Video Tutorial 

dạng bài tập

1. Bài Toán Liệt Kê

Dạng bài này thường yêu cầu bạn đếm hoặc liệt kê các phần tử trong mảng 2 chiều thỏa mãn tính chất cho trước như : số nguyên tố, thuận nghịch, hoàn hảo, fibonacci...

Đối với dạng bài tập này bạn chỉ cần biết duyệt mảng 2 chiều là có thể làm được.

Ví dụ 1 : Tìm phần tử nhỏ nhất, lớn nhất trong mảng 2 chiều

#include "stdio.h"
#include "math.h"

int main(){
    int n = 4, m = 4;
    int a[4][4] = {
        {3, 1, 0, 7},
        {2, 5, 10, 3},
        {3, 7, 4, 1},
        {10, 2, 0, 3}
    };
    int min_val = 1000000000, max_val = -1000000000;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(a[i][j] > max_val){
                max_val = a[i][j];
            }
            if(a[i][j] < min_val){
                min_val = a[i][j];
            }
        }
    }
    printf("Gia tri nho nhat : %d\n", min_val);
    printf("Gia tri lon nhat : %d\n", max_val);
    return 0;
}

Output : 

Gia tri nho nhat : 0
Gia tri lon nhat : 10

Ví dụ 2 : Liệt kê các số Fibonacci trong mảng 2 chiều

#include "stdio.h"
#include "math.h"

int fibo(long long n){
    long long F[100];
    F[0] = 0; F[1] = 1;
    for(int i = 2; i <= 92; i++){
        F[i] = F[i - 1] + F[i - 2];
    }
    for(int i = 0; i <= 92; i++){
        if(n == F[i]) return 1;
    }
    return 0;
}

int main(){
    int n = 4, m = 4;
    int a[4][4] = {
        {3, 1, 0, 7},
        {2, 5, 10, 3},
        {3, 7, 4, 1},
        {10, 2, 0, 3}
    };
    printf("Cac so fibonacci : ");
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(fibo(a[i][j])){
                printf("%d ", a[i][j]);
            }
        }
    }
    return 0;
}

Output : 

Cac so fibonacci : 3 1 0 2 5 3 3 1 2 0 3 


2. Bài Toán Xét Hàng, Cột

Dạng bài tập này thường yêu cầu các bạn xét từng hàng hoặc từng cột của mảng 2 chiều. 

Đối với bài toán xét theo hàng bạn duyệt như bình thường còn đối với bài toán duyệt theo cột thì bạn cần để vòng for ngoài duyệt theo cột và vòng for con bên trong duyệt theo hàng. 

Ví dụ 1 : Tính tổng từng hàng, từng cột của mảng 2 chiều

#include "stdio.h"
#include "math.h"

int main(){
    int n = 4, m = 4;
    int a[4][4] = {
        {3, 1, 0, 7},
        {2, 5, 10, 3},
        {3, 7, 4, 1},
        {10, 2, 0, 3}
    };
    //Duyệt theo hàng, i là hàng, j là cột
    for(int i = 0; i < n; i++){
        int tong = 0;
        for(int j = 0; j < m; j++){
            tong += a[i][j];
        }
        printf("Tong hang %d : %d\n", i, tong);
    }
    //Duyệt theo cột, i là cột, j là hàng
    for(int i = 0; i < m; i++){
        int tong = 0;
        for(int j = 0; j < n; j++){
            tong += a[j][i];
        }
        printf("Tong cot %d : %d\n", i, tong);
    }
    return 0;
}

Output : 

Tong hang 0 : 11
Tong hang 1 : 20
Tong hang 2 : 15
Tong hang 3 : 15
Tong cot 0 : 18
Tong cot 1 : 15
Tong cot 2 : 14
Tong cot 3 : 14

Ví dụ 2 : Tìm hàng có nhiều số nguyên tố nhất 

#include "stdio.h"
#include "math.h"

int prime(int n){
    for(int i = 2; i <= sqrt(n); i++){
        if(n % i == 0) return false;
    }
    return n > 1;
}

int main(){
    int n = 4, m = 4;
    int a[4][4] = {
        {3, 1, 0, 7},
        {2, 5, 10, 3},
        {3, 7, 4, 1},
        {10, 2, 0, 3}
    };
    //Duyệt theo hàng, i là hàng, j là cột
    int res = 0, hang = -1;
    for(int i = 0; i < n; i++){
        int dem = 0;
        for(int j = 0; j < m; j++){
            if(prime(a[i][j])){
                ++dem;
            }
        }
        if(dem > res){
            res = dem; hang = i;
        }
    }
    printf("Hang %d co nhieu so nguyen to nhat\n", hang);
    printf("So luong so nguyen to o hang %d : %d\n", hang, res);
    return 0;
}

Output : 

Hang 1 co nhieu so nguyen to nhat
So luong so nguyen to o hang 1 : 3

Ví dụ 3 : Tìm cột có nhiều số nguyên tố nhất, nếu có nhiều cột có cùng số nguyên tố thì chọn cột có số thứ tự lớn hơn

#include "stdio.h"
#include "math.h"

int prime(int n){
    for(int i = 2; i <= sqrt(n); i++){
        if(n % i == 0) return false;
    }
    return n > 1;
}

int main(){
    int n = 4, m = 4;
    int a[4][4] = {
        {3, 1, 0, 7},
        {2, 5, 10, 3},
        {3, 7, 4, 1},
        {10, 2, 0, 3}
    };
    //Duyệt theo hàng, i là hàng, j là cột
    int res = 0, cot = -1;
    for(int i = 0; i < m; i++){
        int dem = 0;
        for(int j = 0; j < n; j++){
            if(prime(a[j][i])){
                ++dem;
            }
        }
        if(dem >= res){
            res = dem; cot = i;
        }
    }
    printf("Cot %d co nhieu so nguyen to nhat\n", cot);
    printf("So luong so nguyen to o cot %d : %d\n", cot, res);
    return 0;
}

Output : 

Cot 3 co nhieu so nguyen to nhat
So luong so nguyen to o cot 3 : 3


3. Hoán Vị Hàng, Cột

Để hoán vị 2 hàng của mảng 2 chiều thì bạn duyệt qua từng cột còn để hoán vị 2 cột thì bạn lại duyệt qua từng hàng.

Ví dụ 1 : Bài toán hoán vị 2 hàng

#include "stdio.h"
#include "math.h"

int main(){
    int n = 4, m = 4;
    int a[4][4] = {
        {3, 1, 0, 7},
        {2, 5, 10, 3},
        {3, 7, 4, 1},
        {10, 2, 0, 3}
    };
    int h1 = 0, h2 = 3;
    for(int i = 0; i < m; i++){
        //a[h1][i] va a[h2][i]
        int tmp = a[h1][i];
        a[h1][i] = a[h2][i];
        a[h2][i] = tmp;
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Output : 

10 2 0 3 
2 5 10 3 
3 7 4 1 
3 1 0 7 

Ví dụ 2 : Bài toán hoán vị 2 cột

#include "stdio.h"
#include "math.h"

int main(){
    int n = 4, m = 4;
    int a[4][4] = {
        {3, 1, 0, 7},
        {2, 5, 10, 3},
        {3, 7, 4, 1},
        {10, 2, 0, 3}
    };
    int c1 = 0, c2 = 3;
    for(int i = 0; i < n; i++){
        //a[i][c1] va a[i][c2]
        int tmp = a[i][c1];
        a[i][c1] = a[i][c2];
        a[i][c2] = tmp;
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Output : 

7 1 0 3 
3 5 10 2 
1 7 4 3 
3 2 0 10 


4. Sắp Xếp Ma Trận Theo Hàng, Cột

Sắp xếp theo hàng

Sắp xếp theo hàng trên ma trận thì bạn có thể tự code một hàm sắp xếp mảng 1 chiều sau đó áp dụng với từng hàng của mảng 2 chiều.

Như mình có nhắc ở phần lý thuyết mảng 2 chiều thì mảng 2 chiều thực chất chính là 1 mảng các mảng 1 chiều, mỗi dòng trên mảng 2 chiều chính là 1 mảng 1 chiều.

Cách 1 : Sắp xếp hàng bằng hàm qsort()

#include "stdio.h"
#include "stdlib.h"

int cmp(const void *a, const void *b){
    int *x = (int*)a;
    int *y = (int*)b;
    return *x - *y;
}

int main(){
    int n = 4, m = 5;
    int a[4][5] = {
        {3, 1, 0, 7, 2},
        {2, 5, 10, 3, 4},
        {3, 17, 4, 1, 7},
        {10, 2, 0, 11, 9}
    };
    for(int i = 0; i < n; i++){
        //sap xep a[i]
        qsort(a[i], m, sizeof(int), cmp);
    }
    printf("Mang 2 chieu sau khi sap xep :\n");
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Output : 

Mang 2 chieu sau khi sap xep :
0 1 2 3 7 
2 3 4 5 10 
1