Khoá học C++ nâng cao
Khóa học C++ Nâng cao là chương trình đào tạo chuyên sâu tiếp nối sau nền tảng cơ bản, nhằm trang bị cho học sinh tư duy thuật toán đỉnh cao, kỹ thuật tái kết hợp đa phương pháp (Hybrid Problem Solving) và làm chủ các cấu trúc dữ liệu phức tạp.
Khóa học tập trung rèn luyện phương pháp giải bài thi đấu thực chiến: từ việc phân tích bản chất toán học, lựa chọn cấu trúc dữ liệu tối ưu, đến kỹ thuật đánh giá độ phức tạp, bắt bẫy biên và cài đặt mã nguồn chuẩn mực đáp ứng trọn vẹn các kỳ thi Học sinh giỏi và Tin học trẻ Bảng B.
Kiến thức trọng tâm & Ghi nhớ
1. KHUNG TƯ DUY CỦA MỌI BÀI LẬP TRÌNH
Mọi bài toán đều bắt đầu bằng chuỗi câu hỏi:
Đề bài → Dữ liệu → Biến → Công thức/Điều kiện
→ Các bước xử lý → Code → Kiểm tra kết quả
Mô hình Input – Process – Output
| Thành phần | Câu hỏi cần trả lời |
|---|---|
| Input | Chương trình nhận những dữ liệu nào? |
| Process | Cần tính toán, kiểm tra hoặc lặp lại việc gì? |
| Output | Cần in ra kết quả nào, theo định dạng nào? |
Trước khi viết code, hãy viết bằng lời hoặc pseudocode:
1. Đọc dữ liệu.
2. Tính hoặc xử lý dữ liệu.
3. Kiểm tra điều kiện nếu có.
4. In kết quả.
Công thức trước code
Không viết code trước khi biết mình đang tính gì.
Bài toán → Công thức hoặc quy tắc → Code
Ví dụ tính diện tích hình chữ nhật:
S = chiều_dài × chiều_rộng
long long area = length * width;
Ví dụ tính trung bình (giữ phần thập phân):
double average = 1.0 * sum / n;
Chuỗi ghi nhớ nền tảng
BIẾN → TÍNH → ĐIỀU KIỆN → LẶP → TÍCH LŨY → MẢNG → HÀM → DEBUG
| Từ khóa | Câu hỏi tự kiểm tra |
|---|---|
| Biến | Tôi cần lưu dữ liệu gì? |
| Tính | Tôi cần công thức nào? |
| Điều kiện | Tôi cần đưa ra quyết định nào? |
| Lặp | Tôi cần làm việc gì nhiều lần? |
| Tích lũy | Tôi cần cộng, đếm, tìm lớn nhất hay nhỏ nhất? |
| Mảng | Tôi có nhiều dữ liệu cùng loại không? |
| Hàm | Tôi có thể tách phần việc nào thành một nhiệm vụ riêng? |
| Debug | Nếu kết quả sai, tôi sẽ kiểm tra từ đâu? |
2. KHUNG CHƯƠNG TRÌNH C++ TỐI THIỂU
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
// 1. Khai báo biến
// 2. Đọc dữ liệu
// 3. Xử lý
// 4. In kết quả
return 0;
}
| Thành phần | Ý nghĩa |
|---|---|
#include <bits/stdc++.h> |
Nạp các thư viện C++ thường dùng trong thi đấu |
using namespace std; |
Cho phép dùng vector, string, cin, cout… trực tiếp |
int main() |
Điểm bắt đầu thực hiện chương trình |
ios::sync_with_stdio(false); |
Tăng tốc nhập/xuất |
cin.tie(nullptr); |
Tối ưu liên kết giữa nhập và xuất |
return 0; |
Kết thúc chương trình thành công |
Giai đoạn đầu chỉ cần tập trung vào dữ liệu – xử lý – kết quả, chưa cần hiểu sâu cơ chế thư viện.
3. BIẾN VÀ KIỂU DỮ LIỆU
Biến là ô nhớ có tên để lưu dữ liệu.
int age = 15; long long population = 9000000000LL; double average = 8.5; char grade = 'A'; string name = "An"; bool passed = true;
| Kiểu | Dùng để lưu | Ví dụ |
|---|---|---|
int |
Số nguyên thông thường | tuổi, số lượng nhỏ |
long long |
Số nguyên lớn hoặc tổng lớn | tổng tiền, tổng mảng |
double |
Số thực | trung bình, kết quả đo |
char |
Một ký tự | 'A', '7' |
string |
Một chuỗi ký tự | "Hello" |
bool |
Đúng hoặc sai | true, false |
Quy tắc chọn kiểu dữ liệu
| Nếu giá trị… | Nên nghĩ đến… |
|---|---|
| Là số đếm nhỏ | int |
Có thể vượt giới hạn int, hoặc là tổng nhiều số |
long long |
| Có phần thập phân | double |
| Là một ký tự duy nhất | char |
| Là nhiều ký tự liên tiếp | string |
| Chỉ có hai trạng thái đúng/sai | bool |
Khi chưa chắc tổng có lớn hay không, hãy cân nhắc dùng
long long.
Khởi tạo biến tích lũy
long long sum = 0;
int count = 0;
int mx = -1000000000;
int mn = 1000000000;
Biến dùng để cộng hoặc đếm phải có giá trị ban đầu đúng. Không dùng biến chưa khởi tạo.
4. NHẬP VÀ XUẤT DỮ LIỆU
int a, b;
cin >> a >> b;
cout << a + b << '\n';
string s;
cin >> s;
cout << s << '\n';
| Lệnh | Ý nghĩa |
|---|---|
cin >> a |
Đọc một giá trị vào biến a |
cin >> a >> b |
Đọc nhiều giá trị liên tiếp |
cout << answer |
In kết quả |
<< '\n' |
Xuống dòng |
Nếu cần đọc cả một dòng có khoảng trắng, có thể dùng:
getline(cin, s);
Trong phần lớn bài thi cơ bản, dữ liệu dạng số hoặc từ không có khoảng trắng có thể đọc bằng cin >>.
Ba mẹo thi đấu thường gặp
// 1. Đọc nhiều bộ test đến khi hết file
int n;
while (cin >> n) {
// xử lý từng bộ test
}
// 2. Đọc dòng có khoảng trắng sau khi đã cin >> n
cin.ignore(numeric_limits<streamsize>::max(), '\n');
getline(cin, s);
// 3. Ép kiểu giữ phần thập phân khi sum là long long
double avg = 1.0 * sum / n;
Cần
#include <bits/stdc++.h>đã bao gồmlimitschonumeric_limits.
5. TOÁN TỬ VÀ BIỂU THỨC
Toán tử số học
| Toán tử | Ý nghĩa | Ví dụ |
|---|---|---|
+ |
Cộng | a + b |
- |
Trừ | a - b |
* |
Nhân | a * b |
/ |
Chia | a / b |
% |
Phần dư | a % b |
Chia nguyên và phần dư
15 / 4 == 3
15 % 4 == 3
Khi cả hai toán hạng là số nguyên, phép / cho phần nguyên. Toán tử % cho phần dư.
| Mẫu | Ý nghĩa |
|---|---|
x % 2 == 0 |
x là số chẵn |
x % 2 != 0 |
x là số lẻ |
x % 10 |
Chữ số cuối của x |
x / 10 |
Bỏ chữ số cuối của x |
a % b == 0 |
a chia hết cho b |
Toán tử so sánh
> < >= <= == !=
| Toán tử | Ý nghĩa |
|---|---|
== |
Bằng nhau |
!= |
Khác nhau |
> |
Lớn hơn |
< |
Nhỏ hơn |
>= |
Lớn hơn hoặc bằng |
<= |
Nhỏ hơn hoặc bằng |
Lưu ý: Đừng nhầm
=(gán) với==(so sánh).
Toán tử logic
| Toán tử | Ý nghĩa | Ví dụ | |||
|---|---|---|---|---|---|
&& |
Và | age >= 10 && age <= 15 |
|||
| `| | ` | Hoặc | `x == 0 | y == 0` | |
! |
Phủ định | !passed |
6. ĐIỀU KIỆN — RẼ NHÁNH
Mẫu cơ bản
if (condition) {
// việc A
} else {
// việc B
}
Mô hình bằng lời:
NẾU điều kiện đúng
thực hiện A
NGƯỢC LẠI
thực hiện B
Nhiều trường hợp
if (score >= 8) {
cout << "Gioi";
} else if (score >= 6.5) {
cout << "Kha";
} else {
cout << "Can co gang";
}
Điều kiện lồng nhau
Chỉ dùng khi quyết định thứ hai phụ thuộc vào quyết định thứ nhất. Hãy viết điều kiện bằng lời trước để tránh rối.
Lỗi thường gặp
| Lỗi | Cách kiểm tra |
|---|---|
Dùng = thay cho == |
Đọc lại mọi điều kiện so sánh |
Nhầm > với >= |
Kiểm tra trường hợp bằng đúng ngưỡng |
| Thiếu trường hợp | Thử giá trị nhỏ nhất, lớn nhất và đúng biên |
| Điều kiện quá phức tạp | Tách thành các biến bool hoặc viết lại bằng lời |
7. VÒNG LẶP – LÀM MỘT VIỆC NHIỀU LẦN
Trước khi viết vòng lặp, trả lời ba câu hỏi:
- Việc gì được lặp lại?
- Biến nào thay đổi sau mỗi lần?
- Khi nào vòng lặp dừng?
for: biết trước số lần hoặc khoảng lặp
for (int i = 0; i < n; i++) {
// xử lý phần tử thứ i
}
Với mảng có n phần tử, chỉ số thường chạy từ 0 đến n - 1.
while: lặp khi điều kiện còn đúng
while (condition) {
// xử lý
// phải có cách làm condition thay đổi
}
Nếu điều kiện không bao giờ sai, chương trình có thể lặp vô hạn.
do..while: thực hiện ít nhất một lần
do {
// xử lý
} while (condition);
Trong phần C++ cơ bản, for và while là hai dạng cần dùng thành thạo nhất.
Vòng lặp lồng nhau
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// xử lý từng cặp (i, j)
}
}
Nếu vòng ngoài chạy N lần và vòng trong chạy M lần, số thao tác thường là O(NM).
8. BỐN MẪU TÍCH LŨY
Tính tổng
long long sum = 0;
for (int x : a) {
sum += x;
}
Đếm phần tử thỏa điều kiện
int count = 0;
for (int x : a) {
if (x % 2 == 0) count++;
}
Tìm giá trị lớn nhất
int mx = a[0];
for (int x : a) {
mx = max(mx, x);
}
Tìm giá trị nhỏ nhất
int mn = a[0];
for (int x : a) {
mn = min(mn, x);
}
Nếu dữ liệu có thể rỗng, không được truy cập
a[0]trước khi kiểm tra kích thước. Có thể khởi tạomx,mntheo giới hạn bài toán.
9. MẢNG, VECTOR VÀ STRING
Mảng và chỉ số
a[0], a[1], a[2], .., a[n - 1]
Chỉ số bắt đầu từ 0. Với
nphần tử, chỉ số hợp lệ là0 … n-1.
Đọc và duyệt mảng
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n; i++) {
cout << a[i] << ' ';
}
Duyệt bằng phần tử
for (int x : a) {
cout << x << ' ';
}
Dùng chỉ số i khi cần biết vị trí hoặc cập nhật a[i]. Dùng x khi chỉ cần đọc từng giá trị.
Các thao tác vector cơ bản
| Lệnh | Ý nghĩa |
|---|---|
vector<int> a(n) |
Tạo vector có n phần tử |
a.size() |
Số phần tử |
a.push_back(x) |
Thêm x vào cuối |
a.pop_back() |
Xóa phần tử cuối |
a[i] |
Truy cập phần tử vị trí i |
a.empty() |
Kiểm tra có rỗng không |
Xử lý string
string s;
cin >> s;
for (int i = 0; i < (int)s.size(); i++) {
if (s[i] == 'A') {
// xử lý ký tự A
}
}
| Biểu thức | Ý nghĩa |
|---|---|
s.size() |
Độ dài xâu |
s[i] |
Ký tự ở vị trí i |
s.front() |
Ký tự đầu |
s.back() |
Ký tự cuối |
10. HÀM — CHIA BÀI TOÁN THÀNH CÁC PHẦN
Hàm là một khối công việc riêng: nhận dữ liệu vào, thực hiện một nhiệm vụ và có thể trả về kết quả.
int square(int x) { return x * x; }
int result = square(5); // result = 25
Mẫu hàm
return_type function_name(parameters) {
// xử lý
return value;
}
Nếu hàm không trả về kết quả, dùng void:
void printLine(int n) {
for (int i = 0; i < n; i++) cout << '-';
cout << '\n';
}
Hàm nên thực hiện một nhiệm vụ rõ ràng. Các tên hàm thường gặp trong bài thuật toán là check(), isPrime(), gcd(), solve() và dfs().
11. GỠ LỖI VÀ KIỂM THỬ
Khi chương trình sai, không đoán bừa. Hãy kiểm tra theo thứ tự:
| Câu hỏi | Việc cần làm |
|---|---|
| Input có đúng không? | Đọc lại định dạng và số lượng dữ liệu |
| Kiểu dữ liệu có đủ lớn không? | Kiểm tra int, long long, phép nhân và tổng |
| Công thức có đúng không? | Tính thủ công bằng một ví dụ nhỏ |
| Điều kiện có đúng không? | Thử trường hợp bằng biên, nhỏ hơn và lớn hơn biên |
| Vòng lặp có chạy đủ không? | Theo dõi giá trị bắt đầu, kết thúc và bước nhảy |
| Chỉ số có hợp lệ không? | Kiểm tra 0 ≤ i < n |
| Kết quả trung gian có đúng không? | In biến tạm tại vị trí cần kiểm tra |
In giá trị trung gian
cerr << "i = " << i << ", sum = " << sum << '\n';
Có thể dùng cout ở bài đơn giản, nhưng phải xóa các dòng debug trước khi nộp nếu output yêu cầu chính xác.
Bộ test tối thiểu
Mỗi bài nên thử:
- Ví dụ mẫu.
- Dữ liệu nhỏ nhất.
- Dữ liệu lớn nhất hoặc gần lớn nhất.
- Trường hợp đúng bằng ngưỡng.
- Trường hợp không có phần tử thỏa điều kiện.
- Trường hợp tất cả phần tử đều thỏa điều kiện.
- Trường hợp có nhiều phần tử bằng nhau.
12. ĐỘ PHỨC TẠP — CHƯƠNG TRÌNH CÓ ĐỦ NHANH?
| Độ phức tạp | Trực giác |
|---|---|
O(1) |
Số thao tác gần như không phụ thuộc kích thước dữ liệu |
O(log N) |
Mỗi bước thu nhỏ đáng kể phạm vi tìm kiếm |
O(N) |
Duyệt dữ liệu một lần |
O(N log N) |
Thường gặp khi sắp xếp |
O(N²) |
Xét mọi cặp hoặc hai vòng lặp theo N |
O(2^N) |
Thử mọi tập con; chỉ phù hợp với N nhỏ |
Quy tắc đọc giới hạn
Nếu N khoảng… |
Có thể cân nhắc… |
|---|---|
N ≤ 20 |
Duyệt tập con, bitmask, quay lui |
N ≤ 10^3 |
Một số lời giải O(N²) |
N ≤ 10^5 hoặc 2 × 10^5 |
O(N), O(N log N) |
N rất lớn |
Công thức, toán học hoặc tối ưu mạnh hơn |
Đây chỉ là quy tắc định hướng. Cần xét thêm số test, hằng số trong chương trình và giới hạn thời gian.
TÓM TẮT MỘT TRANG
BIẾN
Tôi cần lưu dữ liệu gì?
TÍNH
Tôi cần công thức nào?
ĐIỀU KIỆN
Tôi cần quyết định điều gì?
LẶP
Tôi cần làm việc gì nhiều lần?
TÍCH LŨY
Tôi cần cộng, đếm, max hay min?
MẢNG
Tôi có nhiều dữ liệu cùng loại không?
HÀM
Tôi có thể tách nhiệm vụ nào thành một khối công việc riêng?
DEBUG
Input, biến, công thức, điều kiện, vòng lặp và kết quả trung gian có đúng không?
Mục tiêu của C++ Cơ bản: Không phải nhớ thật nhiều câu lệnh, mà là nhìn một bài toán đơn giản và biết biến nó thành các bước có thể lập trình được.
Giảng viên phụ trách
Thầy Phan Tuấn Kiệt
• 20+ năm kinh nghiệm giảng dạy Tin học văn phòng
• Chuyên môn: Đào tạo Scratch
cơ bản - nâng cao - luyện thi, Python cơ bản - nâng cao - luyện thi, C++ - nâng cao
- luyện thi...
Lộ trình chi tiết
Chương 1: Module 01: Số Học & Đại Số Đồng Dư Nâng Cao
Module 01: Số Học & Đại Số Đồng Dư Nâng CaoBài 1 - Số Học Cơ Bản & Chuyên Sâu Miễn phí
Đã liên kết 22 bài tập trong khối Danh sách bài tập.
Bài 2 - Modulo & Lũy Thừa Nhanh Miễn phí
Đã liên kết 22 bài tập trong khối Danh sách bài tập.
Chương 2: Module 02: Kỹ Thuật Tìm Kiếm & Xử Lý Mảng Đa Chiều
Module 02: Kỹ Thuật Tìm Kiếm & Xử Lý Mảng Đa ChiềuBài 3 - Tìm Kiếm Nhị Phân Nâng Cao Miễn phí
Đã liên kết 22 bài tập trong khối Danh sách bài tập.
Bài 4 - Kỹ Thuật Mảng: Hai Con Trỏ, Cửa Sổ Trượt, Mảng Tiền Tố & Mảng Hiệu Miễn phí
Đã liên kết 22 bài tập trong khối Danh sách bài tập.
Chương 3: Module 03: Đệ Quy, Chia Để Trị, Meet In The Middle & Mặt Nạ Bit
Module 03: Đệ Quy, Chia Để Trị, Meet In The Middle & Mặt Nạ BitBài 5 - Đệ Quy, Chia Để Trị & Kỹ Thuật Meet in the Middle Miễn phí
Đã liên kết 22 bài tập trong khối Danh sách bài tập.
Bài 6 - Phép Toán Bit & Mặt Nạ Bit Nâng Cao Miễn phí
Đã liên kết 24 bài tập trong khối Danh sách bài tập.
Chương 4: Module 04: Thuật Toán Tham Lam & Quy Hoạch Động Cơ Bản
Module 04: Thuật Toán Tham Lam & Quy Hoạch Động Cơ BảnBài 7 - Thuật Toán Tham Lam (Greedy) Miễn phí
Đã liên kết 22 bài tập trong khối Danh sách bài tập.
Bài 8 - Quy Hoạch Động Cơ Bản (Dynamic Programming) Miễn phí
Đã liên kết 26 bài tập trong khối Danh sách bài tập.
Chương 5: Module 05: Cấu Trúc Dữ Liệu Đơn Điệu, STL C++ Nâng Cao & Đại Số Tổ Hợp
Module 05: Cấu Trúc Dữ Liệu Đơn Điệu, STL C++ Nâng Cao & Đại Số Tổ HợpBài 9 - Ngăn Xếp, Hàng Đợi & Deque Miễn phí
Đã liên kết 22 bài tập trong khối Danh sách bài tập.
Bài 10 - Thư Viện STL C++ Nâng Cao Miễn phí
Đã liên kết 22 bài tập trong khối Danh sách bài tập.
Bài 11 - Tổ Hợp, Hoán Vị & Xác Suất Cơ Bản Miễn phí
Đã liên kết 22 bài tập trong khối Danh sách bài tập.
Chương 6: Module 06: Đồ Thị, Cây Truy Vấn Đoạn, Digit DP & Xử Lý Chuỗi
Module 06: Đồ Thị, Cây Truy Vấn Đoạn, Digit DP & Xử Lý ChuỗiBài 12 - Lý Thuyết Đồ Thị Cơ Bản & Nâng Cao Miễn phí
Đã liên kết 26 bài tập trong khối Danh sách bài tập.
Bài 13 - Cây Phân Đoạn & Cây Fenwick (Segment Tree & BIT) Miễn phí
Đã liên kết 26 bài tập trong khối Danh sách bài tập.
Bài 14 - Quy Hoạch Động Chữ Số (Digit DP) Miễn phí
Đã liên kết 22 bài tập trong khối Danh sách bài tập.
Bài 15 - Xử Lý Chuỗi Ký Tự, String Hashing & Số Nguyên Lớn Miễn phí
Đã liên kết 24 bài tập trong khối Danh sách bài tập.
Kết quả đạt được sau khóa học
- Làm chủ các cấu trúc dữ liệu & thuật toán nâng cao (Segment Tree, BIT, Digit DP, Graph, String Hashing)
- Thành thạo kỹ thuật tái kết hợp đa phương pháp (MITM, Two Pointers + Prefix Sum, Sàng SPF)
- Nâng cao kỹ năng phân tích độ phức tạp, tối ưu thời gian chạy và quản lý bộ nhớ
- Tự tin chinh phục các kỳ thi Học sinh giỏi các cấp và Tin học trẻ Bảng B
Đối tượng phù hợp
Độ tuổi & Trình độ
Khóa học được thiết kế tối ưu cho đối tượng 11-18 tuổi, trình độ Nâng cao.