Hướng dẫn cho Chia hết 2 (THTA Vòng Sơ loại Toàn quốc 2025 - Lần 2)
Chỉ sử dụng khi thực sự cần thiết như một cách tôn trọng tác giả và người viết hướng dẫn này.
Chép code từ bài hướng dẫn để nộp bài là hành vi có thể dẫn đến khóa tài khoản.
Chép code từ bài hướng dẫn để nộp bài là hành vi có thể dẫn đến khóa tài khoản.
Tóm tắt đề bài
Cho bốn chữ số \(A, B, C, D\) (có thể trùng nhau, có thể có \(0\)). Hỏi từ bốn chữ số này có thể lập được bao nhiêu số có hai chữ số:
- Chia hết cho \(2\) (tức chữ số hàng đơn vị là chữ số chẵn),
- Không có chữ số \(0\) ở đầu (tức chữ số hàng chục \(\neq 0\)).
Cần đếm số lượng giá trị khác nhau thỏa điều kiện.
Phân tích
- Số có hai chữ số dạng \(10x + y\) với:
- \(x\) là chữ số hàng chục, yêu cầu \(x \neq 0\),
- \(y\) là chữ số hàng đơn vị, yêu cầu \(y\) chẵn (\(y \in \{0,2,4,6,8\}\)).
- Ta được phép chọn \(x\) và \(y\) từ tập \(\{A,B,C,D\}\):
- Đề không nói “mỗi chữ số chỉ dùng một lần”, và code AC cũng duyệt mọi cặp \((x,y)\) từ 4 chữ số (cho phép dùng cùng giá trị nhiều lần).
- Do có thể có chữ số trùng nhau, nhiều cách chọn khác nhau có thể tạo ra cùng một số (ví dụ \(A=2, C=2\)). Vì vậy phải loại trùng kết quả.
Hướng giải quyết
Nhận xét
- Điều kiện chia hết cho \(2\) chỉ phụ thuộc vào chữ số hàng đơn vị \(y\).
- Điều kiện “không có \(0\) ở đầu” chỉ phụ thuộc vào chữ số hàng chục \(x\).
- Không gian tìm kiếm rất nhỏ: chỉ có \(4\) lựa chọn cho \(x\) và \(4\) lựa chọn cho \(y\) \(\Rightarrow\) tối đa \(16\) số cần xét.
Thuật toán (đúng như code AC)
- Đọc \(A,B,C,D\) và lưu vào mảng
digits. - Duyệt mọi cặp có thứ tự \((x, y)\) trong
digits:- Nếu \(x \neq 0\) và \(y\) chẵn thì tạo số \(n = 10x + y\) và đưa vào danh sách.
- Dùng
setđể loại trùng các số tạo được. - In ra kích thước của
set.
Lưu ý/pitfall thường gặp
- Quên loại trùng khi các chữ số đầu vào bị lặp (ví dụ \(2,4,2,4\)).
- Nhầm điều kiện: số chia hết cho \(2\) phụ thuộc chữ số hàng đơn vị, không phải hàng chục.
- Cần loại các trường hợp hàng chục bằng \(0\) (không được tính các số dạng
0y).
Độ phức tạp
- Thời gian: \(O(16)\), coi như \(O(1)\).
- Bộ nhớ: \(O(1)\) (tối đa lưu vài chục số hai chữ số).
Code tham khảo
Python
A = int(input())
B = int(input())
C = int(input())
D = int(input())
digits = [A, B, C, D]
b = []
# Duyệt mọi cặp (hàng chục, hàng đơn vị)
for x in digits:
for y in digits:
# Không cho phép 0 ở đầu, và phải chia hết cho 2 => y chẵn
if x != 0 and y % 2 == 0:
b.append(x * 10 + y)
# Loại trùng các số tạo được và đếm
print(len(set(b)))
Bình luận