Bài 1: Lập trình là gì? Lập trình thuật toán để làm gì? Nên học C++ hay Python?
Lời mở đầu
Từ trước tới giờ trên web mình chủ yếu chia sẻ lời giải các bài tập lập trình và Toán. Nhiều bạn nhắn hỏi: "Thầy ơi em chưa biết gì hết thì nên bắt đầu từ đâu?". Vậy nên mình mở thêm series Nhập môn lập trình thuật toán, đi từ con số 0, mỗi bài một chủ đề, có hình minh hoạ, có chạy tay từng dòng code ngay trên trang và có bài tập kèm gợi ý để các bạn tự luyện.
Trong cả series, ngôn ngữ chính là C++ (ngôn ngữ phổ biến nhất trong các kỳ thi lập trình), nhưng mỗi đoạn code mình đều viết kèm bản Python tương ứng để các bạn đối chiếu. Bạn nào đang học Python ở trường thì cũng theo được nhé.
Lộ trình bài viết, bấm vào từng phần để nhảy tới:
Phần 1Lập trình là gì?
Máy tính rất nhanh (tính được hàng trăm triệu phép tính mỗi giây) nhưng lại không tự biết làm gì cả. Nó chỉ làm đúng y chang những gì con người ra lệnh, từng bước một, không hơn không kém. Lập trình chính là việc viết ra các câu lệnh để "dạy" máy tính giải quyết một công việc nào đó. Tập hợp các câu lệnh đó gọi là chương trình (program), còn ngôn ngữ dùng để viết gọi là ngôn ngữ lập trình (C++, Python, Java, Pascal…).
Mình hay ví von thế này: lập trình giống như viết một công thức nấu ăn cho một người phụ bếp cực kỳ nhanh tay nhưng không có chút "suy nghĩ" nào. Nếu công thức ghi "cho muối vừa ăn" thì anh ta chịu chết, vì "vừa ăn" là bao nhiêu? Phải ghi rõ "cho 5 gam muối". Viết chương trình cũng vậy: mọi thứ phải rõ ràng, chính xác, không mơ hồ.
Đây là chương trình đầu tiên mình muốn các bạn nhìn thấy: đọc 2 số rồi in ra tổng. Ở bài này các bạn chưa cần hiểu từng chữ trong code (bài 2 mình sẽ giải thích kỹ), chỉ cần bấm Tiếp ▶ trong khung "Chạy tay" để xem máy tính thực hiện lần lượt từng dòng như thế nào, các "chiếc hộp" biến thay đổi ra sao và màn hình in ra gì. Các bạn có thể sửa dữ liệu vào để thử luôn.
Code C++ và Python
#include <iostream>
using namespace std;
int main(){
int a, b;
cin >> a >> b;
int tong = a + b;
cout << tong;
return 0;
}
a, b = map(int, input().split())
tong = a + b
print(tong)
#include, main, khai báo kiểu int…), còn Python chỉ có 3 dòng. Đây là khác biệt đầu tiên giữa 2 ngôn ngữ mà phần 3 mình sẽ phân tích kỹ.Phần 2Thuật toán là gì? Lập trình thuật toán có ý nghĩa gì?
Thuật toán (algorithm) là một dãy hữu hạn các bước rõ ràng để từ dữ liệu vào (Input) đi đến kết quả mong muốn (Output). Nói cho dễ hiểu: thuật toán là cách làm, còn chương trình là cách làm đó được viết lại bằng ngôn ngữ lập trình để máy hiểu. Một thuật toán đúng phải có các tính chất:
- Hữu hạn: phải dừng sau một số bước, không được chạy mãi mãi.
- Xác định: mỗi bước phải rõ ràng, ai làm (hay máy nào chạy) cũng ra cùng một kết quả.
- Đúng đắn: với mọi dữ liệu vào hợp lệ đều cho ra kết quả đúng, chứ không phải chỉ đúng với ví dụ của đề.
- Có Input và Output rõ ràng.
Ví dụ: tìm số lớn nhất trong một dãy số
Giả sử thầy đọc cho các bạn nghe lần lượt từng số: $3, 8, 2, 9, 4$ và hỏi số nào lớn nhất. Các bạn sẽ làm thế nào? Rất tự nhiên: nghe số đầu tiên thì ghi nhớ nó, nghe tới số nào lớn hơn số đang nhớ thì thay số đang nhớ bằng số đó. Hết dãy thì số đang nhớ là đáp án. Viết thành các bước:
Thuật toán tìm số lớn nhất (Input: $n$ và dãy $n$ số; Output: số lớn nhất)
- Đọc $n$. Đọc số đầu tiên, gán cho
mx(tạm coi là lớn nhất). - Lặp lại với các số thứ $2, 3, \ldots, n$: đọc số đó vào $x$; nếu $x \gt mx$ thì gán $mx = x$.
- In ra
mx.
Cùng chạy tay thuật toán này nhé. Ô xanh là số lớn nhất "đang nhớ", ô vàng là số đang xét. Đoạn code có dùng câu lệnh if (bài 3) và vòng lặp for (bài 4), các bạn cứ xem cho quen mắt trước:
Code C++ và Python
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int mx;
cin >> mx;
for(int i = 2; i <= n; i++){
int x;
cin >> x;
if(x > mx){
mx = x;
}
}
cout << mx;
return 0;
}
n = int(input())
a = list(map(int, input().split()))
mx = a[0]
for i in range(1, n):
if a[i] > mx:
mx = a[i]
print(mx)
Vậy học lập trình thuật toán để làm gì?
Có bạn sẽ hỏi: "Tìm số lớn nhất thì nhìn là biết, cần gì thuật toán?". Với 5 số thì đúng là vậy, nhưng nếu có 1 triệu số thì sao? Hoặc bài toán khó hơn như tìm đường đi ngắn nhất giữa 2 thành phố, xếp thời khoá biểu cho cả trường? Lúc đó mình phải nghĩ ra cách làm đúng và còn phải đủ nhanh. Đó chính là việc của lập trình thuật toán. Theo kinh nghiệm hơn 12 năm dạy học của mình, học thuật toán mang lại cho các bạn:
Mô phỏng trực quan. Đọc các bước rồi mà vẫn khó hình dung máy tính “giữ ngôi vương” thế nào? Em bấm Tiếp để xem từng lần so sánh trên đúng dãy 3, 8, 2, 9, 4, rồi thử tự nhập dãy khác nhé.
Cùng một bài toán có thể có nhiều thuật toán, và có cách nhanh hơn hẳn cách khác. Em xem hai cách tính tổng 1 + 2 + … + n chạy “thi” với nhau, để ý số phép tính mỗi bên phải làm:
Phần 3Ngôn ngữ lập trình – nên chọn C++ hay Python?
Biên dịch và thông dịch
Máy tính thực chất chỉ hiểu mã máy (các dãy số 0 và 1). Chúng ta viết code bằng ngôn ngữ gần với tiếng Anh như C++, Python, nên cần một chương trình "phiên dịch" sang mã máy. Có 2 kiểu phiên dịch chính:
C++ dịch toàn bộ chương trình ra mã máy trước rồi mới chạy; Python dịch tới đâu chạy tới đó.
Học lập trình thuật toán nên chọn C++ hay Python?
Đây là câu hỏi mình được hỏi nhiều nhất. Câu trả lời ngắn gọn: muốn đi thi lập trình thuật toán thì nên lấy C++ làm ngôn ngữ chính, còn Python rất tốt để làm quen, để học ở trường và để dùng sau này. Cùng phân tích kỹ nhé:
- ✅ Chạy rất nhanh nhờ được biên dịch ra mã máy.
- ✅ Thư viện STL cực mạnh cho thi đấu:
sort,vector,set,map,priority_queue,lower_bound… - ✅ Được hỗ trợ ở mọi kỳ thi và hệ thống chấm bài; hầu hết lời giải, tài liệu thuật toán đều viết bằng C++.
- ✅ Phải khai báo kiểu dữ liệu nên hiểu rõ máy tính lưu dữ liệu thế nào (tràn số, bộ nhớ…).
- ⚠️ Cú pháp dài hơn, khắt khe hơn: thiếu một dấu
;là báo lỗi.
- ✅ Cú pháp ngắn gọn, dễ đọc, gần với ngôn ngữ tự nhiên, rất hợp để mới làm quen.
- ✅ Số nguyên không giới hạn độ lớn, không lo tràn số.
- ✅ Được dạy nhiều ở trường phổ thông; dùng rộng rãi trong AI, phân tích dữ liệu, tự động hoá.
- ⚠️ Chạy chậm hơn C++ nhiều lần, nên với bài giới hạn thời gian chặt dễ bị quá thời gian (TLE) dù thuật toán đúng.
- ⚠️ Ít cấu trúc dữ liệu dựng sẵn cho thi đấu bằng C++ (ví dụ không có sẵn
setcó thứ tự).
Để các bạn thấy rõ chênh lệch tốc độ, mình cho chạy thật cùng một đoạn code: vòng lặp $10^8$ (100 triệu) lần, mỗi lần cộng thêm i % 7 vào tổng:
Code đo tốc độ C++ và Python
#include <iostream>
using namespace std;
int main(){
long long s = 0;
for(int i = 1; i <= 100000000; i++){
s += i % 7;
}
cout << s;
return 0;
}
s = 0
for i in range(1, 100000001):
s += i % 7
print(s)
| Ngôn ngữ | Kết quả | Thời gian chạy |
|---|---|---|
| C++ (g++ -O2) | 299999997 | ≈ 0,10 giây |
| Python 3.13 | 299999997 | ≈ 8,1 giây |
Cùng kết quả nhưng Python chậm hơn khoảng 80 lần. Trong khi đề thi thường giới hạn 1 giây cho mỗi test, và kinh nghiệm là trong 1 giây C++ chạy được khoảng $10^8$ phép tính đơn giản, còn Python chỉ khoảng vài triệu đến $10^7$. Đó là lý do bài Bộ số tam giác mình khuyên nộp C++.
- Học sinh muốn thi HSG, chuyên Tin, Tin học trẻ, đội tuyển: học C++ ngay từ đầu. Đừng sợ "khó", cú pháp C++ dùng cho thi đấu chỉ cần một phần nhỏ, học vài tuần là quen.
- Đang học Python ở trường: cứ học song song, mỗi bài trong series đều có code Python để đối chiếu. Hiểu thuật toán rồi thì đổi ngôn ngữ chỉ là chuyện cú pháp.
- Sinh viên, người đi làm luyện phỏng vấn: chọn ngôn ngữ mình dùng thạo nhất; nếu chưa có thì C++ hoặc Python đều được, vì phỏng vấn chủ yếu chấm cách nghĩ.
Biên dịch và thông dịch nghe hơi trừu tượng. Em xem mô phỏng dưới đây: cùng một chương trình nhỏ có vòng lặp, hai ngôn ngữ phải “dịch” bao nhiêu lần, là hiểu vì sao C++ chạy nhanh hơn Python nhiều:
Phần 4Học thế nào cho hiệu quả?
- Tự gõ lại code, đừng chỉ đọc. Gõ sai, báo lỗi, tự sửa là cách nhớ cú pháp nhanh nhất.
- Chạy tay trước khi chạy máy. Lấy giấy bút, tự mô phỏng chương trình với một bộ dữ liệu nhỏ như các khung "Chạy tay từng dòng code" trên trang. Đây là kỹ năng quan trọng nhất để tìm lỗi sai.
- Tự làm bài tập ít nhất 20–30 phút rồi mới xem gợi ý; bí quá mới xem code tham khảo.
- Học đều mỗi ngày, mỗi ngày 1–2 bài còn hơn một tuần ngồi 1 buổi.
- Xong series nhập môn này thì đi tiếp theo Lộ trình học thuật toán từ A đến Z trên web.
Bài tiếp theo (bài 2) mình sẽ hướng dẫn cài phần mềm Code::Blocks để viết code C++, viết chương trình đầu tiên, nhập xuất dữ liệu và các kiểu dữ liệu cơ bản.
Bài tậpLuyện tư duy thuật toán (chưa cần code)
Các bài dưới đây chủ yếu luyện cách suy nghĩ, các bạn lấy giấy bút làm nhé. Bài nào có code tham khảo thì để sau khi học xong bài 2 – 4 quay lại đọc cũng được.
Với mỗi bài toán sau, hãy chỉ ra Input (dữ liệu vào) và Output (kết quả cần đưa ra): (a) Tính diện tích hình chữ nhật. (b) Kiểm tra một số nguyên là chẵn hay lẻ. (c) Tìm số nhỏ nhất trong 3 số. (d) Đếm xem trong một câu có bao nhiêu chữ cái a.
💡 Gợi ý / đáp án
(b) Input: số nguyên $n$ – Output: chữ "chẵn" hoặc "lẻ".
(c) Input: 3 số $a, b, c$ – Output: số nhỏ nhất.
(d) Input: một câu (xâu ký tự) – Output: một số nguyên là số lần xuất hiện của
a.Mẹo: đọc đề bài nào cũng tự hỏi "đề cho mình cái gì, bắt mình đưa ra cái gì" trước tiên.
Viết các bước (bằng lời) của thuật toán tìm số nhỏ nhất trong dãy $n$ số. Sau đó chạy tay thuật toán của bạn với dãy $3, 8, 2, 9, 4$.
5
3 8 2 9 42💡 Gợi ý
mn), gặp số nào nhỏ hơn mn thì cập nhật. Chạy tay: mn = 3 → gặp 8 (không nhỏ hơn) → gặp 2, cập nhật mn = 2 → gặp 9, 4 không nhỏ hơn → kết quả 2.Xem code tham khảo (C++ / Python)
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int mn;
cin >> mn; // tạm coi số đầu tiên là nhỏ nhất
for(int i = 2; i <= n; i++){
int x;
cin >> x;
if(x < mn){ // gặp số nhỏ hơn thì cập nhật
mn = x;
}
}
cout << mn;
return 0;
}
n = int(input())
a = list(map(int, input().split()))
mn = a[0] # tạm coi số đầu tiên là nhỏ nhất
for i in range(1, n):
if a[i] < mn: # gặp số nhỏ hơn thì cập nhật
mn = a[i]
print(mn)
Cần tính $S = 1 + 2 + 3 + \cdots + n$. Hãy nghĩ ra 2 cách làm khác nhau. Với $n = 10^9$, mỗi cách cần khoảng bao nhiêu phép cộng? Cách nào nhanh hơn?
1055💡 Gợi ý
Cách 2 (công thức Gauss): ghép cặp $1 + n$, $2 + (n-1)$, … mỗi cặp có tổng $n + 1$, có $n/2$ cặp nên $S = \dfrac{n(n+1)}{2}$ – chỉ 1 phép nhân, 1 phép chia, chạy tức thì. Đây chính là ý nghĩa của thuật toán: cùng bài toán, cách nghĩ khác nhau thì tốc độ chênh nhau khủng khiếp. Lưu ý với $n = 10^9$ thì kết quả cỡ $5 \cdot 10^{17}$, trong C++ phải dùng kiểu
long long (bài 2 sẽ học).Xem code tham khảo (C++ / Python)
#include <iostream>
using namespace std;
int main(){
long long n;
cin >> n;
// Cách 2: công thức Gauss, chỉ 1 phép tính dù n lớn cỡ nào
long long s = n * (n + 1) / 2;
cout << s;
return 0;
}
n = int(input())
# Cách 2: công thức Gauss, chỉ 1 phép tính dù n lớn cỡ nào
s = n * (n + 1) // 2
print(s)
Cho thuật toán: B1. Gán $x = 5$. B2. Gán $x = x \times 2$. B3. Gán $y = x - 3$. B4. Gán $x = y + x$. B5. In ra $x$ và $y$. Hỏi kết quả in ra là gì?
💡 Đáp án
Cốc A đựng nước cam, cốc B đựng nước chanh. Làm sao để cốc A đựng nước chanh, cốc B đựng nước cam? Hãy viết các bước. Sau đó áp dụng cho bài toán: hoán đổi giá trị của 2 biến $a$ và $b$.
💡 Gợi ý
t = a; a = b; b = t;. Nếu viết a = b; b = a; thì sai vì sau lệnh đầu, giá trị cũ của $a$ đã bị mất. Trong C++ có sẵn hàm swap(a, b), còn Python viết gọn a, b = b, a.- Không biết học gì trước, học gì sau, học lan man nên kiến thức bị hổng.
- Bí bài không ai gỡ, ngồi cả buổi vẫn không ra rồi bỏ cuộc.
- Code chạy được nhưng không đủ điểm, không biết sai ở đâu, chậm ở đâu.
- Không có đề thi thử và người chấm, nên không biết mình đang ở mức nào.
- Dễ nản giữa chừng khi không có ai theo sát.
- Lộ trình 111 buổi video sắp sẵn từ dòng code đầu tiên đến đề HSG thật của các tỉnh.
- Thầy trực tiếp gỡ bí, chữa bài cho từng em qua nhóm Zalo riêng.
- Hệ thống chấm bài tự động 24/7 và thi thử HSG hằng tuần để biết chính xác mình đang ở đâu.
- Đóng học phí một lần, thầy kèm lâu dài: từ thi chuyên Tin đến HSG quốc gia và cả khi lên đại học.

Nhận xét
Đăng nhận xét