Phép chia có dư và chia hết
Phép chia có dư là phép toán các bạn học từ lớp 3, nhưng lại xuất hiện trong rất nhiều bài thi lập trình: đổi giây ra giờ phút, tách chữ số, tìm thứ trong tuần, kiểm tra số chẵn lẻ, đếm bội số… Bài này giúp các bạn dùng thành thạo hai phép toán chia lấy phần nguyên và chia lấy dư.
Phép chia có dư
Phần tiêu đề “Phép chia có dư”Chia 17 viên kẹo cho 5 bạn, mỗi bạn được 3 viên, còn thừa 2 viên:
17 = 5 × 3 + 2
- 3 là thương (phần nguyên): mỗi bạn được mấy viên.
- 2 là số dư: còn thừa mấy viên. Số dư luôn nhỏ hơn số chia: nếu thừa từ 5 viên trở lên thì chia tiếp được cho mỗi bạn thêm 1 viên.
Khi số dư bằng 0, ta nói a chia hết cho b. Ví dụ 15 chia hết cho 5 vì 15 = 5 × 3 + 0.
Trong lập trình:
| Phép toán | Python | C++ | Ví dụ với 17 và 5 |
|---|---|---|---|
| Chia lấy phần nguyên | 17 // 5 | 17 / 5 | 3 |
| Chia lấy dư | 17 % 5 | 17 % 5 | 2 |
| Kiểm tra chia hết | a % b == 0 | a % b == 0 | 17 không chia hết cho 5 |
Lưu ý: trong C++, nếu cả hai số đều là số nguyên thì / là chia lấy phần
nguyên (17 / 5 bằng 3). Trong Python, / luôn cho số thực (17 / 5 bằng
3.4), muốn lấy phần nguyên phải dùng //.
Tách các chữ số của một số
Phần tiêu đề “Tách các chữ số của một số”Với số 2026:
2026 % 10bằng 6: chia cho 10 thì số dư chính là chữ số hàng đơn vị.2026 // 10bằng 202: chia lấy phần nguyên cho 10 là bỏ chữ số cuối.
Lặp lại hai bước trên cho tới khi số bằng 0, ta lấy được lần lượt từng chữ số từ phải sang trái: 6, 2, 0, 2. Ví dụ tính tổng các chữ số:
n = 2026tong = 0while n > 0: tong += n % 10 # lấy chữ số cuối n //= 10 # bỏ chữ số cuốiprint(tong) # 10#include <iostream>using namespace std;
int main() { long long n = 2026; int tong = 0; while (n > 0) { tong += n % 10; // lấy chữ số cuối n /= 10; // bỏ chữ số cuối } cout << tong << endl; // 10 return 0;}Cùng cách nghĩ đó: n % 100 cho hai chữ số cuối, n // 100 bỏ hai chữ số
cuối.
Dấu hiệu chia hết
Phần tiêu đề “Dấu hiệu chia hết”Các dấu hiệu học ở tiểu học rất có ích khi số quá lớn, không lưu được vào biến số nguyên (ví dụ số có 1000 chữ số, phải đọc vào dưới dạng xâu):
| Chia hết cho | Dấu hiệu |
|---|---|
| 2 | chữ số tận cùng là 0, 2, 4, 6, 8 |
| 5 | chữ số tận cùng là 0 hoặc 5 |
| 10 | chữ số tận cùng là 0 |
| 3 | tổng các chữ số chia hết cho 3 |
| 9 | tổng các chữ số chia hết cho 9 |
Vì sao tổng chữ số lại quyết định chia hết cho 9? Lấy số 2026:
2026 = 2 × 1000 + 0 × 100 + 2 × 10 + 6
Mà 1000 = 999 + 1, 100 = 99 + 1, 10 = 9 + 1, và 999, 99, 9 đều chia hết cho 9. Bỏ hết các phần chia hết cho 9 đi, chỉ còn lại 2 + 0 + 2 + 6. Vậy 2026 và tổng các chữ số của nó có cùng số dư khi chia cho 9.
Đếm số chia hết cho k trong một đoạn
Phần tiêu đề “Đếm số chia hết cho k trong một đoạn”Ví dụ: có bao nhiêu số chia hết cho 4 trong đoạn từ 10 đến 30?
Cách thứ nhất là thử từng số, gặp số chia hết cho 4 thì đếm. Ta được 12, 16, 20, 24, 28, tức là 5 số. Cách này đúng, nhưng nếu đoạn dài tới 1018 số thì máy tính phải thử 1018 số, ước lượng hơn 300 năm.
Cách thứ hai dùng một nhận xét đơn giản: từ 1 đến n có đúng n // k số chia hết cho k. Chẳng hạn từ 1 đến 30 có 30 // 4 = 7 số chia hết cho 4 (4, 8, 12, …, 28), vì cứ mỗi 4 số liên tiếp thì có đúng một số chia hết cho 4.
Muốn đếm trong đoạn từ a đến b, ta lấy số lượng từ 1 đến b, bỏ đi số lượng từ 1 đến a - 1:
| Bước | Phép tính | Kết quả |
|---|---|---|
| Từ 1 đến 30 | 30 // 4 | 7 |
| Từ 1 đến 9 | 9 // 4 | 2 (là 4 và 8) |
| Từ 10 đến 30 | 7 - 2 | 5 |
def dem_chia_het(a, b, k): return b // k - (a - 1) // k
print(dem_chia_het(10, 30, 4)) # 5print(dem_chia_het(1, 10**18, 7)) # 142857142857142857 - chạy ngay lập tức#include <iostream>using namespace std;
long long demChiaHet(long long a, long long b, long long k) { return b / k - (a - 1) / k;}
int main() { cout << demChiaHet(10, 30, 4) << endl; // 5 cout << demChiaHet(1, 1000000000000000000LL, 7) << endl; // 142857142857142857 return 0;}Lưu ý: trừ đi số lượng từ 1 đến a - 1, không phải đến a. Nếu trừ đến a thì khi a chia hết cho k (ví dụ đoạn 12 đến 30), số 12 bị bỏ mất.
Đây là ý quan trọng nhất của mục Toán tin: một công thức nhỏ thay cho cả một vòng lặp lớn.
Vòng tròn: thứ trong tuần, giờ trên đồng hồ
Phần tiêu đề “Vòng tròn: thứ trong tuần, giờ trên đồng hồ”Những thứ lặp lại theo vòng đều dùng phép chia lấy dư:
- Hôm nay là thứ Hai, 100 ngày nữa là thứ mấy? Cứ 7 ngày lại về thứ Hai, mà 100 = 7 × 14 + 2, nên chỉ cần đi thêm 2 ngày: thứ Tư.
- Bây giờ là 22 giờ, 5 tiếng nữa là mấy giờ? (22 + 5) % 24 = 27 % 24 = 3 giờ sáng.
Lưu ý: nếu các vị trí được đánh số từ 1 (bạn số 1, 2, …, n) thì
không dùng được ngay % n, vì số dư chạy từ 0 đến n - 1. Cách làm là trừ 1 để
đưa về đánh số từ 0, chia lấy dư, rồi cộng 1 trở lại: (x - 1) % n + 1.
Số dư của số âm
Phần tiêu đề “Số dư của số âm”Python và C++ cho kết quả khác nhau khi chia số âm:
| Phép tính | Python | C++ |
|---|---|---|
-7 % 3 | 2 | -1 |
-7 // 3 (Python), -7 / 3 (C++) | -3 | -2 |
Trong toán, số dư luôn không âm: -7 = 3 × (-3) + 2, nên số dư là 2. Python làm đúng như toán, còn C++ thì giữ dấu của số bị chia. Muốn C++ luôn cho số dư không âm, viết:
long long soDu(long long a, long long b) { return (a % b + b) % b; // -7, 3 cho ra 2}Lỗi này hay gặp trong bài thi khi tính lùi ngày, lùi giờ (ví dụ 2 giờ trước của 1 giờ sáng): chương trình C++ cho ra giờ âm.
Luyện tập
Phần tiêu đề “Luyện tập”Gồm 21 bài, chia thành 4 nhóm từ dễ đến khó. Mỗi bài có một dữ liệu kiểm tra: các bạn chạy chương trình của mình với dữ liệu đó rồi so với đáp số.
Nhóm 1. Thương và số dư
Phần tiêu đề “Nhóm 1. Thương và số dư”Bài 1. Chẵn hay lẻ
Phần tiêu đề “Bài 1. Chẵn hay lẻ”Nhập số nguyên n (|n| ≤ 1018). In ra CHAN nếu n là số chẵn, ngược lại in ra LE.
Ví dụ: nhập 2026 thì in ra CHAN.
Kiểm tra: nhập -2027.
Bài 2. Chia kẹo
Phần tiêu đề “Bài 2. Chia kẹo”Có n viên kẹo chia đều cho k bạn (1 ≤ n, k ≤ 1018). In ra số kẹo mỗi bạn nhận được và số kẹo còn thừa, cách nhau một dấu cách.
Ví dụ: nhập 17 5 thì in ra 3 2.
Kiểm tra: nhập 2026 12.
Bài 3. Đổi giây
Phần tiêu đề “Bài 3. Đổi giây”Nhập số nguyên n (0 ≤ n ≤ 109) là số giây. Đổi ra giờ, phút, giây và in ra ba số trên một dòng, cách nhau một dấu cách.
Ví dụ: nhập 3725 thì in ra 1 2 5.
Kiểm tra: nhập 100000.
Bài 4. Số xe ít nhất
Phần tiêu đề “Bài 4. Số xe ít nhất”Có n học sinh đi tham quan, mỗi xe chở được nhiều nhất k học sinh (1 ≤ n, k ≤ 1018). In ra số xe ít nhất cần thuê.
Ví dụ: nhập 90 45 thì in ra 2.
Kiểm tra: nhập 1000 45.
Bài 5. Năm nhuận
Phần tiêu đề “Bài 5. Năm nhuận”Năm nhuận là năm chia hết cho 400, hoặc chia hết cho 4 nhưng không chia hết cho 100. Nhập năm n (1 ≤ n ≤ 109), in ra YES nếu n là năm nhuận, ngược lại in ra NO.
Ví dụ: nhập 2024 thì in ra YES.
Kiểm tra: nhập 2100.
Nhóm 2. Làm việc với chữ số
Phần tiêu đề “Nhóm 2. Làm việc với chữ số”Bài 6. Tổng chữ số
Phần tiêu đề “Bài 6. Tổng chữ số”Nhập số nguyên dương n (n ≤ 1018). In ra tổng các chữ số của n.
Ví dụ: nhập 2026 thì in ra 10.
Kiểm tra: nhập 987654321.
Bài 7. Đếm chữ số
Phần tiêu đề “Bài 7. Đếm chữ số”Nhập số nguyên dương n (n ≤ 1018). In ra số chữ số của n.
Ví dụ: nhập 2026 thì in ra 4.
Kiểm tra: nhập 1234567890123.
Bài 8. Chữ số đầu tiên
Phần tiêu đề “Bài 8. Chữ số đầu tiên”Nhập số nguyên dương n (n ≤ 1018). In ra chữ số đầu tiên (bên trái nhất) của n.
Ví dụ: nhập 2026 thì in ra 2.
Kiểm tra: nhập 5123456789.
Bài 9. Số đảo ngược
Phần tiêu đề “Bài 9. Số đảo ngược”Nhập số nguyên dương n (n ≤ 1017). In ra số nhận được khi viết các chữ số của n theo thứ tự ngược lại (bỏ các chữ số 0 ở đầu nếu có).
Ví dụ: nhập 2026 thì in ra 6202.
Kiểm tra: nhập 987001.
Bài 10. Số đối xứng
Phần tiêu đề “Bài 10. Số đối xứng”Số đối xứng là số đọc xuôi hay đọc ngược đều giống nhau, ví dụ 12321. Nhập số nguyên dương n (n ≤ 1017), in ra YES nếu n là số đối xứng, ngược lại in ra NO.
Ví dụ: nhập 2026 thì in ra NO.
Kiểm tra: nhập 1234321.
Bài 11. Số rất lớn chia hết cho 9
Phần tiêu đề “Bài 11. Số rất lớn chia hết cho 9”Nhập số nguyên dương n có không quá 100000 chữ số. In ra YES nếu n chia hết cho 9, ngược lại in ra NO.
Ví dụ: nhập 2026 thì in ra NO.
Kiểm tra: nhập 123456789123456789.
Bài 12. Cộng chữ số đến khi còn một chữ số
Phần tiêu đề “Bài 12. Cộng chữ số đến khi còn một chữ số”Nhập số nguyên dương n (n ≤ 1018). Cộng các chữ số của n được một số mới, lại cộng các chữ số của số mới… cho tới khi chỉ còn một chữ số. In ra chữ số đó.
Ví dụ: nhập 2026 thì in ra 1.
Kiểm tra: nhập 987654321.
Nhóm 3. Đếm bằng công thức
Phần tiêu đề “Nhóm 3. Đếm bằng công thức”Bài 13. Đếm bội số trong đoạn
Phần tiêu đề “Bài 13. Đếm bội số trong đoạn”Nhập ba số nguyên dương a, b, k (a ≤ b ≤ 1018, k ≤ 1018). In ra số lượng số chia hết cho k trong đoạn từ a đến b.
Ví dụ: nhập 10 30 4 thì in ra 5.
Kiểm tra: nhập 1000 2026 7.
Bài 14. Chia hết cho 3 hoặc 5
Phần tiêu đề “Bài 14. Chia hết cho 3 hoặc 5”Nhập số nguyên dương n (n ≤ 1018). Đếm xem từ 1 đến n có bao nhiêu số chia hết cho 3 hoặc chia hết cho 5.
Ví dụ: nhập 10 thì in ra 5.
Kiểm tra: nhập 100.
Bài 15. Tổng các bội số
Phần tiêu đề “Bài 15. Tổng các bội số”Nhập hai số nguyên dương n, k (k ≤ n ≤ 109). In ra tổng các số chia hết cho k trong đoạn từ 1 đến n.
Ví dụ: nhập 20 4 thì in ra 60.
Kiểm tra: nhập 1000 7.
Bài 16. Đếm năm nhuận
Phần tiêu đề “Bài 16. Đếm năm nhuận”Nhập số nguyên dương n (n ≤ 1018). Đếm số năm nhuận từ năm 1 đến năm n (quy tắc năm nhuận như bài 5).
Ví dụ: nhập 100 thì in ra 24.
Kiểm tra: nhập 2026.
Nhóm 4. Vòng tròn và số dư
Phần tiêu đề “Nhóm 4. Vòng tròn và số dư”Bài 17. Thứ trong tuần
Phần tiêu đề “Bài 17. Thứ trong tuần”Ngày 1/1/2026 là thứ Năm. Nhập số nguyên n (0 ≤ n ≤ 1018). In ra thứ của ngày cách ngày 1/1/2026 đúng n ngày về sau (Thứ Hai, Thứ Ba, …, Thứ Bảy, Chủ nhật).
Ví dụ: nhập 3 thì in ra Chủ nhật.
Kiểm tra: nhập 1000.
Bài 18. Phát kẹo vòng tròn
Phần tiêu đề “Bài 18. Phát kẹo vòng tròn”n bạn ngồi thành vòng tròn, đánh số từ 1 đến n. Cô giáo phát lần lượt từng viên kẹo, bắt đầu từ bạn số 1, đến bạn số n thì quay lại bạn số 1. Nhập n và số kẹo m (1 ≤ n, m ≤ 1018). In ra số thứ tự của bạn nhận viên kẹo cuối cùng.
Ví dụ: nhập 3 5 thì in ra 2.
Kiểm tra: nhập 7 100.
Bài 19. Số dư không âm
Phần tiêu đề “Bài 19. Số dư không âm”Nhập hai số nguyên a, b (|a| ≤ 1018, 1 ≤ b ≤ 109). In ra số dư r của a khi chia cho b, với 0 ≤ r và r nhỏ hơn b. Chương trình phải chạy đúng cả khi a âm.
Ví dụ: nhập -7 3 thì in ra 2.
Kiểm tra: nhập -17 5.
Bài 20. Lùi đồng hồ
Phần tiêu đề “Bài 20. Lùi đồng hồ”Bây giờ là h giờ (0 ≤ h ≤ 23). Hỏi t giờ trước (0 ≤ t ≤ 109) là mấy giờ? In ra một số từ 0 đến 23.
Ví dụ: nhập 1 2 thì in ra 23.
Kiểm tra: nhập 3 100.
Bài 21. Chữ số tận cùng của lũy thừa
Phần tiêu đề “Bài 21. Chữ số tận cùng của lũy thừa”Nhập số nguyên dương n (n ≤ 106). In ra chữ số tận cùng của 7n (7 nhân với chính nó n lần).
Ví dụ: nhập 2 thì in ra 9.
Kiểm tra: nhập 2026.