Danh mục: 6 BÀI TẬP C++ CHUẨN THI HỌC SINH GIỎI MỚI NHẤT 2026

6 BÀI TẬP C++ CHUẨN THI HỌC SINH GIỎI MỚI NHẤT 2026

6 BÀI TẬP C++ CHUẨN THI HỌC SINH GIỎI MỚI NHẤT 2026

Tài liệu này tổng hợp các bài toán lập trình C++ từ căn bản đến nâng cao được thiết kế hoàn toàn theo format các kỳ thi Học sinh giỏi (HSG) các cấp. Mỗi bài toán đều quy định rõ ràng tệp dữ liệu vào, tệp kết quả ra, giới hạn dữ liệu (subtasks) và kèm theo mã nguồn giải mẫu tối ưu, sử dụng định danh biến bằng tiếng Việt trực quan, giúp học sinh nắm vững bản chất thuật toán.

Bài 1: Tính toán kích thước hình học (HCN)

Bài toán: Cho hai số thực dương là chiều dài và chiều rộng của một mảnh vườn hình chữ nhật. Tính chu vi và diện tích mảnh vườn. Kết quả làm tròn đến 2 chữ số thập phân.

  • Thời gian chạy: 1.0 giây

  • Dữ liệu vào (HCN.INP): Một dòng chứa hai số thực $a$$b$ (0 < a, b ≤ 10^6).

  • Dữ liệu ra (HCN.OUT): Một dòng chứa chu vi và diện tích, cách nhau một khoảng trắng.

Ví dụ:

  • Input (HCN.INP): 5.5 3.2

  • Output (HCN.OUT): 17.40 17.60

Code C++ tham khảo:

C++

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    freopen("HCN.INP", "r", stdin);
    freopen("HCN.OUT", "w", stdout);

    double dai, rong;
    if (cin >> dai >> rong) {
        double chu_vi = (dai + rong) * 2;
        double dien_tich = dai * rong;
        cout << fixed << setprecision(2) << chu_vi << " " << dien_tich << endl;
    }
    return 0;
}

Bài 2: Khảo sát số nguyên tố lớn (SNT)

Bài toán: Kiểm tra số nguyên dương $N$ có phải là số nguyên tố hay không.

  • Thời gian chạy: 1.0 giây

  • Dữ liệu vào (SNT.INP): Số nguyên dương $N$.

    • Subtask 1 (60%): N ≤ 10^6

    • Subtask 2 (40%): N ≤ 10^12

  • Dữ liệu ra (SNT.OUT): In ra YES nếu là số nguyên tố, ngược lại in NO.

Ví dụ:

  • Input (SNT.INP): 97

  • Output (SNT.OUT): YES

Code C++ tham khảo:

C++

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    freopen("SNT.INP", "r", stdin);
    freopen("SNT.OUT", "w", stdout);

    long long n; 
    cin >> n;

    if (n < 2) {
        cout << "NO\n";
        return 0;
    }

    bool la_snt = true;
    long long can_bac_hai = sqrt(n);
    
    for (long long i = 2; i <= can_bac_hai; i++) {
        if (n % i == 0) {
            la_snt = false;
            break;
        }
    }

    if (la_snt) cout << "YES\n";
    else cout << "NO\n";
    
    return 0;
}

Bài 3: Thống kê ký tự nguyên âm (CHUOI)

Bài toán: Đếm số lượng nguyên âm (‘a’, ‘e’, ‘i’, ‘o’, ‘u’) trong một chuỗi ký tự.

  • Thời gian chạy: 1.0 giây

  • Dữ liệu vào (CHUOI.INP): Chuỗi ký tự $S$ (chiều dài ≤ 1000).

  • Dữ liệu ra (CHUOI.OUT): Số lượng nguyên âm đếm được.

Ví dụ:

  • Input (CHUOI.INP): Lap trinh C++ Chuan HSG

  • Output (CHUOI.OUT): 5

Code C++ tham khảo:

C++

#include <iostream>
#include <string>
using namespace std;

int main() {
    freopen("CHUOI.INP", "r", stdin);
    freopen("CHUOI.OUT", "w", stdout);

    string van_ban;
    getline(cin, van_ban); 

    int bien_dem = 0;
    for (int i = 0; i < van_ban.length(); i++) {
        char ky_tu = tolower(van_ban[i]);
        if (ky_tu == 'a' || ky_tu == 'e' || ky_tu == 'i' || ky_tu == 'o' || ky_tu == 'u') {
            bien_dem++;
        }
    }

    cout << bien_dem << endl;
    return 0;
}

Bài 4: Sắp xếp và tối ưu mảng số (SAPXEP)

Bài toán: Sắp xếp mảng $N$ số nguyên theo thứ tự tăng dần.

  • Thời gian chạy: 1.0 giây

  • Dữ liệu vào (SAPXEP.INP): * Dòng 1: Số nguyên $N$ (N ≤ 10^5).

    • Dòng 2: $N$ số nguyên cách nhau một dấu cách.

  • Dữ liệu ra (SAPXEP.OUT): Mảng đã sắp xếp tăng dần.

Ví dụ:

  • Input (SAPXEP.INP):

    5

    12 -3 7 0 5

  • Output (SAPXEP.OUT): -3 0 5 7 12

Code C++ tham khảo:

C++

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    freopen("SAPXEP.INP", "r", stdin);
    freopen("SAPXEP.OUT", "w", stdout);

    int so_luong;
    if (cin >> so_luong) {
        vector<int> danh_sach(so_luong);
        
        for (int i = 0; i < so_luong; i++) {
            cin >> danh_sach[i];
        }

        sort(danh_sach.begin(), danh_sach.end());

        for (int i = 0; i < so_luong; i++) {
            cout << danh_sach[i] << " ";
        }
        cout << endl;
    }
    return 0;
}

Bài 5: Tối giản phân số bằng OOP (PHANSO)

Bài toán: Dùng lập trình hướng đối tượng xây dựng lớp Phân số để cộng 2 phân số và in ra kết quả tối giản.

  • Thời gian chạy: 1.0 giây

  • Dữ liệu vào (PHANSO.INP): 4 số nguyên: Tử 1, Mẫu 1, Tử 2, Mẫu 2 (trong khoảng -10^4 đến 10^4).

  • Dữ liệu ra (PHANSO.OUT): Phân số tổng tối giản (nếu mẫu là 1 chỉ in tử số).

Ví dụ:

  • Input (PHANSO.INP): 1 6 2 3

  • Output (PHANSO.OUT): 5/6

Code C++ tham khảo:

C++

#include <iostream>
#include <cmath>
using namespace std;

class PhanSo {
private:
    long long tu, mau;

    long long tim_ucln(long long a, long long b) {
        a = abs(a); b = abs(b);
        while (b != 0) {
            long long tam = b;
            b = a % b;
            a = tam;
        }
        return a;
    }

public:
    PhanSo(long long t = 0, long long m = 1) {
        tu = t;
        mau = (m == 0) ? 1 : m;
    }

    void toi_gian() {
        long long ucln = tim_ucln(tu, mau);
        tu /= ucln;
        mau /= ucln;
        if (mau < 0) { 
            tu = -tu;
            mau = -mau;
        }
    }

    PhanSo cong(PhanSo doi_tac) {
        PhanSo ket_qua;
        ket_qua.tu = this->tu * doi_tac.mau + doi_tac.tu * this->mau;
        ket_qua.mau = this->mau * doi_tac.mau;
        ket_qua.toi_gian();
        return ket_qua;
    }

    void in_ket_qua() {
        if (mau == 1) cout << tu << endl;
        else cout << tu << "/" << mau << endl;
    }
};

int main() {
    freopen("PHANSO.INP", "r", stdin);
    freopen("PHANSO.OUT", "w", stdout);

    long long t1, m1, t2, m2;
    if (cin >> t1 >> m1 >> t2 >> m2) {
        PhanSo ps1(t1, m1), ps2(t2, m2);
        PhanSo tong = ps1.cong(ps2);
        tong.in_ket_qua();
    }
    return 0;
}

Bài 6: Tìm số xuất hiện nhiều nhất (TIMSO)

Bài toán: Tìm số xuất hiện nhiều nhất trong dãy. Nếu có nhiều số cùng số lần xuất hiện, chọn số nhỏ nhất.

  • Thời gian chạy: 1.0 giây

  • Dữ liệu vào (TIMSO.INP): * Dòng 1: $N$ (N ≤ 10^5).

    • Dòng 2: $N$ số nguyên.

  • Dữ liệu ra (TIMSO.OUT): Giá trị số tìm được và số lần xuất hiện.

Ví dụ:

  • Input (TIMSO.INP):

    7

    2 3 5 2 3 8 2

  • Output (TIMSO.OUT): 2 3

Code C++ tham khảo:

C++

#include <iostream>
#include <map>
using namespace std;

int main() {
    freopen("TIMSO.INP", "r", stdin);
    freopen("TIMSO.OUT", "w", stdout);

    int n;
    if (cin >> n) {
        map<int, int> bo_dem;
        int so_nhap;
        
        for (int i = 0; i < n; i++) {
            cin >> so_nhap;
            bo_dem[so_nhap]++; 
        }

        int max_tan_suat = 0;
        int gia_tri_toi_uu = 0;

        for (auto phan_tu : bo_dem) {
            if (phan_tu.second > max_tan_suat) {
                max_tan_suat = phan_tu.second;
                gia_tri_toi_uu = phan_tu.first;
            }
        }

        cout << gia_tri_toi_uu << " " << max_tan_suat << endl;
    }
    return 0;
}

Tags: #HocLapTrinhC #LapTrinhC++ #ThiHSGTinHoc #CodeC++CoBan #GiaiThuatC++ #DeThiTinHoc #TuHocC++