Các bài toán thuật toán cơ bản và kỹ thuật xử lý trong ngôn ngữ C

Phân loại cấp độ điểm số bằng cấu trúc Switch-Case

Để phân loại điểm số thành các cấp độ (A, B, C, D, F), chúng ta có thể thực hiện phép chia nguyên điểm số cho 10. Kết quả của phép chia này sẽ được đưa vào hàm switch để xác định giá trị trả về tương ứng. Lưu ý rằng trong cấu trúc switch, lệnh break đóng vai trò cực kỳ quan trọng. Nếu thiếu break, chương trình sẽ tiếp tục thực thi các khối lệnh bên dưới (fall-through) ngay cả khi không khớp điều kiện, dẫn đến kết quả sai lệch.

Tính tổng các chữ số của một số nguyên

Bài toán yêu cầu tính tổng các chữ số cấu thành nên một số nguyên n. Có hai phương pháp chính để giải quyết:

  • Cách 1 (Vòng lặp): Sử dụng vòng lặp while, liên tục lấy n chia dư cho 10 để lấy chữ số cuối cùng, cộng dồn vào biến tổng, sau đó chia nguyên n cho 10 để loại bỏ chữ số đó. Quá trình lặp lại cho đến khi n bằng 0.
  • Cách 2 (Đệ quy/Điều kiện): Kiểm tra nếu n nhỏ hơn 10 thì trả về chính nó. Ngược lại, thực hiện cộng số dư của n cho 10 với kết quả của việc gọi lại hàm với giá trị n/10.

Tính lũy thừa bằng phương pháp đệ quy

Việc tính giá trị $x^n$ có thể được tối ưu hóa thông qua mô hình đệ quy chia để trị (divide and conquer). Bằng cách chia nhỏ số mũ, chúng ta giảm bớt số lượng phép nhân cần thực hiện, giúp thuật toán vận hành hiệu quả hơn.

Tìm kiếm các cặp số nguyên tố sinh đôi dưới 100

Số nguyên tố sinh đôi là cặp số nguyên tố có khoảng cách giữa chúng là 2 đơn vị. Dưới đây là cách triển khai hàm kiểm tra số nguyên tố và tìm kiếm các cặp số này:

#include <stdio.h>
#include <stdbool.h>

bool kiem_tra_nguyen_to(int n) {
    if (n < 2) return false;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

int main() {
    int dem = 0;
    printf("Cac cap so nguyen to sinh doi < 100:\n");
    for (int i = 2; i <= 97; i++) {
        if (kiem_tra_nguyen_to(i) && kiem_tra_nguyen_to(i + 2)) {
            printf("(%d, %d)\n", i, i + 2);
            dem++;
        }
    }
    printf("Tong cong co %d cap.\n", dem);
    return 0;
}

Tính tổ hợp chập m của n phần tử

Bài toán tính tổ hợp $C(n, m)$ có thể giải bằng hai cách:

Phương pháp lặp (Sử dụng công thức giai thừa):

#include <stdio.h>

long long tinh_to_hop_lap(int n, int m) {
    if (m > n) return 0;
    long long tu_so = 1, mau_so = 1;
    for (int i = 1; i <= m; i++) {
        tu_so *= (n - i + 1);
        mau_so *= i;
    }
    return tu_so / mau_so;
}

Phương pháp đệ quy (Dựa trên tam giác Pascal):

#include <stdio.h>

int tinh_to_hop_de_quy(int n, int m) {
    if (m == 0 || m == n) return 1;
    if (m > n) return 0;
    return tinh_to_hop_de_quy(n - 1, m) + tinh_to_hop_de_quy(n - 1, m - 1);
}

Tìm ước chung lớn nhất (GCD) của ba số nguyên

Để tìm GCD của ba số a, b, và c, chúng ta tìm GCD của hai số đầu tiên, sau đó lấy kết quả đó tìm GCD với số còn lại.

#include <stdio.h>

int tim_gcd(int x, int y) {
    while (y != 0) {
        int tam = x % y;
        x = y;
        y = tam;
    }
    return x;
}

int main() {
    int a, b, c;
    while (scanf("%d %d %d", &a, &b, &c) != EOF) {
        int ket_qua = tim_gcd(tim_gcd(a, b), c);
        printf("UCLN cua %d, %d, %d la: %d\n", a, b, c, ket_qua);
    }
    return 0;
}

In hình kim tự tháp ngược bằng ký tự

Sử dụng các vòng lặp lồng nhau để điều khiển khoảng cách và số lượng ký tự in ra trên mỗi dòng, tạo thành cấu trúc hình học đối xứng.

#include <stdio.h>

void in_hinh(int n) {
    for (int i = n; i >= 1; i--) {
        // In khoang cach
        for (int j = 0; j < n - i; j++) {
            printf("\t");
        }
        // In phan dau
        for (int j = 0; j < 2 * i - 1; j++) {
            printf(" O\t");
        }
        printf("\n");
        
        // In phan than
        for (int j = 0; j < n - i; j++) {
            printf("\t");
        }
        for (int j = 0; j < 2 * i - 1; j++) {
            printf("<H>\t");
        }
        printf("\n");
        
        // In phan chan
        for (int j = 0; j < n - i; j++) {
            printf("\t");
        }
        for (int j = 0; j < 2 * i - 1; j++) {
            printf("I I\t");
        }
        printf("\n\n");
    }
}

int main() {
    int n;
    printf("Nhap n: ");
    if (scanf("%d", &n) == 1) {
        in_hinh(n);
    }
    return 0;
}

Thẻ: C-Language Algorithms Recursion Number-Theory Combinatorics

Đăng vào ngày 17 tháng 05 lúc 08:56