Trả lời nhanh
Dãy số a bao gồm n số tự nhiên chẵn đầu tiên. Số tự nhiên chẵn thứ i (đếm từ i = 0) là 2 × i, nên chỉ cần cho i chạy từ 0 đến n − 1 và thêm 2 × i vào danh sách A. Chương trình ngắn nhất: n = int(input()), A = [2 * i for i in range(n)], print(A). Với n = 6, màn hình in ra [0, 2, 4, 6, 8, 10].
Đề bài và phân tích yêu cầu
Đây là bài Vận dụng 1 trang 118, Tin học 10 Kết nối tri thức (phần lập trình Python với kiểu dữ liệu danh sách): viết chương trình nhập n từ bàn phím, tạo và in ra màn hình dãy số A gồm n số tự nhiên chẵn đầu tiên.
Trước khi gõ lệnh, em xác định rõ ba thành phần của bài toán:
| Thành phần | Nội dung |
|---|---|
| Đầu vào (Input) | Một số tự nhiên n nhập từ bàn phím |
| Xử lí | Tạo danh sách A chứa đúng n số tự nhiên chẵn nhỏ nhất, theo thứ tự tăng dần |
| Đầu ra (Output) | In danh sách A ra màn hình |
Lưu ý về số 0: trong chương trình Toán phổ thông, tập số tự nhiên bắt đầu từ 0 và 0 là số chẵn. Vì vậy n số tự nhiên chẵn đầu tiên là 0, 2, 4, …, 2(n − 1). Nếu thầy cô quy ước bắt đầu từ 2 thì em chỉ cần sửa một chỗ (xem phần biến thể bên dưới).
Ý tưởng thuật toán
Có hai cách nghĩ, cả hai đều đúng:
- Dùng công thức: số chẵn đứng ở vị trí i (i = 0, 1, 2, …) chính là 2 × i. Lặp i từ 0 đến n − 1 là có đủ n số, không cần kiểm tra gì thêm.
- Dùng phép kiểm tra chẵn lẻ: duyệt lần lượt các số tự nhiên m = 0, 1, 2, …; số nào chia hết cho 2 (m % 2 == 0) thì thêm vào A; dừng khi A đã có đủ n phần tử.
Cách thứ nhất chạy nhanh hơn vì mỗi vòng lặp sinh ngay một số chẵn. Cách thứ hai dài hơn nhưng giúp em luyện cấu trúc while và câu lệnh if, rất hay được hỏi trong bài kiểm tra.
Chương trình Python hoàn chỉnh
Cách 1: Vòng lặp for và lệnh append()
n = int(input(“Nhập n: “))
A = []
for i in range(n):
A.append(2 * i)
print(“Dãy A:”, A)
Lệnh A = [] tạo danh sách rỗng. Mỗi lần lặp, A.append(2 * i) thêm số chẵn tiếp theo vào cuối danh sách. Vì range(n) sinh ra n giá trị 0, 1, …, n − 1, danh sách A có đúng n phần tử.
Cách 2: Vòng lặp while kết hợp kiểm tra chẵn lẻ
n = int(input(“Nhập n: “))
A = []
m = 0
while len(A) < n:
if m % 2 == 0:
A.append(m)
m = m + 1
print(A)
Điều kiện len(A) < n bảo đảm vòng lặp dừng ngay khi A đủ n số. Một lỗi hay gặp là viết điều kiện theo biến đếm m (ví dụ while m < n): khi đó em chỉ lấy được các số chẵn nhỏ hơn n, tức khoảng n/2 số, không đủ yêu cầu.
Cách 3: Biểu thức tạo danh sách (list comprehension)
n = int(input(“Nhập n: “))
A = [2 * i for i in range(n)]
print(A)
Đây là cách viết gọn nhất, gộp cả vòng lặp và lệnh thêm phần tử vào một dòng.
Cách 4: Dùng range với bước nhảy 2
n = int(input(“Nhập n: “))
A = list(range(0, 2 * n, 2))
print(A)
range(0, 2 * n, 2) sinh các số 0, 2, 4, … và dừng trước 2n, nên cũng cho đúng n số. Hàm list() chuyển dãy đó thành danh sách.
Chạy thử và kiểm tra kết quả
Với dữ liệu nhập n = 6, cả bốn chương trình đều in ra:
[0, 2, 4, 6, 8, 10]
Bảng mô phỏng Cách 1 với n = 4 giúp em thấy rõ danh sách thay đổi qua từng vòng lặp:
| Vòng lặp | i | 2 * i | Danh sách A sau vòng lặp |
|---|---|---|---|
| 1 | 0 | 0 | [0] |
| 2 | 1 | 2 | [0, 2] |
| 3 | 2 | 4 | [0, 2, 4] |
| 4 | 3 | 6 | [0, 2, 4, 6] |
Để tự kiểm tra, em có thể in thêm len(A) (phải bằng n) và sum(A). Tổng n số tự nhiên chẵn đầu tiên (tính cả 0) bằng n(n − 1); với n = 6 thì tổng là 30, đúng với kết quả 0 + 2 + 4 + 6 + 8 + 10.
Biến thể thường gặp
Bắt đầu từ số 2 (không tính số 0)
Chỉ cần đổi khoảng chạy thành A = [2 * i for i in range(1, n + 1)]. Với n = 6, kết quả là [2, 4, 6, 8, 10, 12].
Kiểm tra dữ liệu nhập và in từng số trên một dòng
n = int(input(“Nhập n: “))
while n < 0:
n = int(input(“n phải là số tự nhiên, nhập lại: “))
A = [2 * i for i in range(n)]
for x in A:
print(x, end=” “)
Vòng while ở đầu buộc người dùng nhập lại nếu n âm. Tham số end=” “ giúp các số in trên cùng một dòng, cách nhau một dấu cách, thay vì in cả danh sách có dấu ngoặc vuông.
Dãy n số tự nhiên lẻ đầu tiên
Số lẻ thứ i là 2 × i + 1, nên chương trình tương ứng là A = [2 * i + 1 for i in range(n)]. Với n = 5, kết quả là [1, 3, 5, 7, 9].
Lỗi hay gặp khi làm bài
- Quên ép kiểu: input() trả về xâu kí tự; viết n = input() rồi dùng range(n) sẽ báo lỗi TypeError. Luôn viết n = int(input()).
- Chưa khởi tạo danh sách: gọi A.append(…) khi chưa có dòng A = [] sẽ báo lỗi NameError.
- Thụt lề sai: nếu lệnh print(A) thụt vào trong vòng lặp, danh sách sẽ bị in nhiều lần, mỗi vòng một lần.
- Nhầm range(n) với range(1, n): range(1, n) chỉ cho n − 1 giá trị, thiếu mất một số.
- Dùng sai toán tử chia: kiểm tra chẵn phải dùng phép lấy dư m % 2 == 0, không dùng m / 2 vì phép chia này luôn cho số thực.
Bài tập tự luyện
- Nhập n, tạo danh sách B gồm n số tự nhiên chia hết cho 3 đầu tiên. Gợi ý: B = [3 * i for i in range(n)]; với n = 4 được [0, 3, 6, 9].
- Nhập n, tạo danh sách C gồm bình phương của các số từ 1 đến n. Gợi ý: C = [i * i for i in range(1, n + 1)]; với n = 5 được [1, 4, 9, 16, 25].
- Nhập danh sách A từ dãy số cho trước, tạo danh sách mới chỉ gồm các phần tử chẵn của A. Gợi ý: dùng vòng for duyệt từng x trong A, nếu x % 2 == 0 thì append vào danh sách mới.
Câu hỏi thường gặp
n số tự nhiên chẵn đầu tiên có bao gồm số 0 không?
Có. Trong chương trình phổ thông, số tự nhiên bắt đầu từ 0 và 0 là số chẵn, nên dãy là 0, 2, 4, …, 2(n − 1). Nếu đề yêu cầu bắt đầu từ 2, em dùng range(1, n + 1).
Lệnh append trong Python dùng để làm gì?
append(x) thêm phần tử x vào cuối danh sách. Ví dụ A = [0, 2] sau lệnh A.append(4) sẽ thành [0, 2, 4].
Vì sao phải viết int(input()) khi nhập n?
Hàm input() luôn trả về xâu kí tự. Phải chuyển sang số nguyên bằng int() thì mới dùng được n trong range() và các phép tính.
Làm sao in các phần tử của danh sách trên cùng một dòng không có ngoặc vuông?
Dùng vòng lặp for x in A: print(x, end=" ") hoặc lệnh print(*A). Cả hai cách đều in các số cách nhau bởi dấu cách.
Tổng n số tự nhiên chẵn đầu tiên bằng bao nhiêu?
Nếu tính cả số 0, tổng là n(n − 1); nếu bắt đầu từ 2, tổng là n(n + 1). Trong Python em có thể kiểm tra bằng sum(A).