Giải Tin Học 10 trang 150

Lời giải chi tiết SGK Lớp 10 · Môn Tin Học · Trang 150–153

Bài 31: Thực hành — Viết chương trình đơn giản

🔍 Kiến thức cần nhớ

Bài thực hành này luyện hai kĩ năng cốt lõi khi lập trình với Python:

1. Sử dụng công cụ gỡ lỗi (debug)

  • Thiết lập điểm dừng (breakpoint) tại một dòng lệnh để chương trình tạm dừng tại đó.
  • Khi dừng, ta có thể quan sát giá trị các biến trung gian để kiểm tra thuật toán chạy đúng hay sai.
  • Nhấn nút chạy tiếp để tiếp tục thực thi sau điểm dừng.

2. Cấu trúc rẽ nhánh lồng nhau và dạng rút gọn if … elif … else

Khi các lệnh if … else lồng nhau, ta nên viết gọn bằng elif:

# Dạng lồng nhau (dài dòng)
if dieu_kien_1:
    khoi_lenh_1
else:
    if dieu_kien_2:
        khoi_lenh_2
    else:
        khoi_lenh_3

# Dạng rút gọn (nên dùng)
if dieu_kien_1:
    khoi_lenh_1
elif dieu_kien_2:
    khoi_lenh_2
else:
    khoi_lenh_3
💡 Mẹo nhớ: Cấu trúc if … elif … elif … else có thể có nhiều nhánh elif liên tiếp và lồng nhau nhiều lần. Python sẽ kiểm tra lần lượt từng điều kiện từ trên xuống, gặp điều kiện đúng đầu tiên thì thực hiện và bỏ qua các nhánh còn lại.

Hai nhiệm vụ mẫu trong bài (phần thực hành có hướng dẫn):

  • Nhiệm vụ 1: Kiểm tra một số n có phải số nguyên tố hay không. Nếu là hợp số thì phân tích n thành tích các thừa số nguyên tố (dùng danh sách NT để lưu các thừa số). Lưu ý: số 1 không phải số nguyên tố và cũng không phải hợp số.
  • Nhiệm vụ 2: Giải phương trình bậc hai ax² + bx + c = 0, xét đầy đủ mọi trường hợp:
  • a = 0, b = 0, c = 0: phương trình vô số nghiệm.
  • a = 0, b = 0, c ≠ 0: phương trình vô nghiệm.
  • a = 0, b ≠ 0: phương trình bậc nhất, có nghiệm duy nhất x = −c/b.
  • a ≠ 0: phương trình bậc hai, nghiệm phụ thuộc vào delta = b² − 4ac.

⚙️ Bài tập

Phần LUYỆN TẬP

Câu 1

Đề bài: Viết chương trình yêu cầu nhập số thực dương a. Chương trình cần kiểm tra dữ liệu nhập: nếu số đã nhập nhỏ hơn hoặc bằng 0 thì thông báo "Nhập sai, số a phải lớn hơn 0. Hãy nhập lại". Chương trình chỉ dừng (nhận giá trị) sau khi người dùng nhập đúng.

Cách 1 — Dùng vòng lặp while với điều kiện kiểm tra

Ý tưởng: lặp lại việc nhập cho đến khi nhập được số dương. Ta cho người dùng nhập lần đầu, sau đó dùng vòng while để kiểm tra: chừng nào a còn ≤ 0 thì còn yêu cầu nhập lại.

a = float(input("Nhập số thực dương a: "))
while a <= 0:
    print("Nhập sai, số a phải lớn hơn 0. Hãy nhập lại")
    a = float(input("Nhập số thực dương a: "))

print("Bạn đã nhập đúng. a =", a)

Giải thích từng bước:

  • Dòng 1: nhập lần đầu, đổi sang số thực bằng float.
  • Vòng while a <= 0: nếu a không hợp lệ (≤ 0) thì in thông báo lỗi và yêu cầu nhập lại.
  • Khi người dùng nhập số > 0, điều kiện a <= 0 sai, vòng lặp kết thúc.
Cách 2 — Dùng vòng lặp vô hạn while True kết hợp break
while True:
    a = float(input("Nhập số thực dương a: "))
    if a > 0:
        break
    print("Nhập sai, số a phải lớn hơn 0. Hãy nhập lại")

print("Bạn đã nhập đúng. a =", a)

Cách này tránh phải viết câu lệnh nhập hai lần. Vòng lặp while True chạy mãi, chỉ thoát (break) khi nhập được số dương.

⚠️ Lưu ý thi: Dạng "kiểm tra và bắt nhập lại" rất hay gặp. Mẹo nhận diện: dùng while với điều kiện sai (điều kiện nhập sai) chứ không phải điều kiện đúng. Lỗi thường gặp là viết while a > 0 (ngược logic) khiến chương trình thoát ngay khi nhập đúng đầu tiên nhưng lặp khi nhập sai.

Câu 2

Đề bài: Viết chương trình in bảng cửu chương ra màn hình:

  • Hàng thứ nhất in ra bảng nhân 1.
  • Hàng thứ hai in ra bảng nhân 2.
  • … (in tiếp tới bảng nhân 9).
Cách 1 — Hai vòng lặp for lồng nhau

Ý tưởng: vòng ngoài chạy theo từng hàng (bảng nhân i, với i từ 1 đến 9), vòng trong chạy theo từng cột (nhân với j từ 1 đến 9).

for i in range(1, 10):
    for j in range(1, 10):
        print(i * j, end="\t")   # \t để các cột thẳng hàng
    print()                       # xuống dòng sau mỗi hàng

Giải thích:

  • range(1, 10) tạo các số 1, 2, …, 9.
  • end="\t" để các kết quả trên cùng một hàng cách nhau bằng dấu Tab, không xuống dòng.
  • print() rỗng để chuyển sang hàng mới sau khi in xong một bảng nhân.
Cách 2 — In kèm phép tính cho dễ đọc

Nếu muốn hiển thị rõ dạng "i × j = kết quả":

for i in range(1, 10):
    for j in range(1, 10):
        print(i, "x", j, "=", i * j, end="   ")
    print()
💡 Mẹo nhớ: Bài in bảng (bảng cửu chương, bảng số, hình tam giác sao) gần như luôn dùng hai vòng for lồng nhau: vòng ngoài = số hàng, vòng trong = số cột trên mỗi hàng. Dùng end= để in trên cùng dòng, print() rỗng để xuống dòng.

Phần VẬN DỤNG

Câu 1

Đề bài: Viết chương trình nhập hai số tự nhiên Y1, Y2 là số năm, Y2 > Y1. Tính xem trong khoảng thời gian từ năm Y1 đến năm Y2 có bao nhiêu năm nhuận. Áp dụng tính xem trong thế kỉ XXI có bao nhiêu năm nhuận.

Quy tắc năm nhuận: Một năm là năm nhuận nếu:

  • Chia hết cho 4 nhưng không chia hết cho 100, hoặc
  • Chia hết cho 400.
Cách 1 — Duyệt từng năm bằng vòng lặp for
Y1 = int(input("Nhập năm bắt đầu Y1: "))
Y2 = int(input("Nhập năm kết thúc Y2: "))

dem = 0
for nam in range(Y1, Y2 + 1):
    if (nam % 4 == 0 and nam % 100 != 0) or (nam % 400 == 0):
        dem = dem + 1

print("Số năm nhuận từ", Y1, "đến", Y2, "là:", dem)

Giải thích:

  • range(Y1, Y2 + 1) duyệt mọi năm từ Y1 đến Y2 (kể cả Y2).
  • Điều kiện năm nhuận viết đúng theo quy tắc bằng phép toán chia lấy dư %.
  • Biến dem đếm số năm thỏa mãn.
Cách 2 — Tính bằng công thức đếm (không cần duyệt)

Số bội của k trong đoạn [1, N] là N // k. Số năm chia hết cho k trong [Y1, Y2] là (Y2 // k) − ((Y1 − 1) // k). Số năm nhuận = (chia hết 4) − (chia hết 100) + (chia hết 400).

Y1 = int(input("Nhập năm bắt đầu Y1: "))
Y2 = int(input("Nhập năm kết thúc Y2: "))

def dem_boi(k):
    return Y2 // k - (Y1 - 1) // k

so_nhuan = dem_boi(4) - dem_boi(100) + dem_boi(400)
print("Số năm nhuận từ", Y1, "đến", Y2, "là:", so_nhuan)

Áp dụng cho thế kỉ XXI (năm 2001 đến 2100):

Các năm chia hết cho 4 trong [2001, 2100]: từ 2004 đến 2100, gồm (2100 − 2004)/4 + 1 = 25 năm. Trong đó năm 2100 chia hết cho 100 nhưng không chia hết cho 400 nên không phải năm nhuận. Vậy thế kỉ XXI có:

25 − 1 = 24 năm nhuận.

⚠️ Lưu ý thi: Lỗi sai kinh điển là chỉ kiểm tra nam % 4 == 0. Phải nhớ thêm điều kiện ngoại lệ với năm tròn thế kỉ (chia hết 100): chỉ nhuận khi chia hết 400. Ví dụ năm 1900, 2100 không nhuận, nhưng 2000 thì nhuận.

Câu 2

Đề bài: Gọi ƯCLN(a, b) là hàm tính ước chung lớn nhất của hai số tự nhiên a, b. Dễ thấy ƯCLN(a, b) = ƯCLN(b, a − b) nếu b > 0, và ƯCLN(a, 0) = a. Từ đó hãy viết chương trình nhập hai số a, b và tính ƯCLN của a và b.

Cách 1 — Đúng theo gợi ý (phép trừ liên tiếp)

Áp dụng trực tiếp hai công thức đề cho. Tuy nhiên công thức ƯCLN(a, b) = ƯCLN(b, a − b) cần bảo đảm a ≥ b để a − b không âm, nên ta đổi chỗ khi cần.

a = int(input("Nhập a: "))
b = int(input("Nhập b: "))

while b > 0:
    if a >= b:
        a = a - b
    else:
        # đổi chỗ để luôn trừ số lớn cho số nhỏ
        a, b = b, a

print("UCLN =", a)

Giải thích:

  • Khi b = 0, theo công thức ƯCLN(a, 0) = a, kết quả chính là a.
  • Chừng nào b > 0, ta thay (a, b) bằng (b, a − b) — ở đây thực hiện bằng cách trừ liên tiếp số lớn cho số nhỏ.
Cách 2 — Thuật toán Euclid bằng phép chia lấy dư (nhanh hơn)

Phép trừ liên tiếp ở Cách 1 chậm khi hai số chênh lệch lớn (ví dụ ƯCLN(1000000, 1)). Thay phép trừ bằng phép chia lấy dư sẽ nhanh hơn rất nhiều, dựa trên ƯCLN(a, b) = ƯCLN(b, a mod b).

def UCLN(a, b):
    while b != 0:
        a, b = b, a % b
    return a

a = int(input("Nhập a: "))
b = int(input("Nhập b: "))
print("UCLN =", UCLN(a, b))

Giải thích:

  • Mỗi bước thay (a, b) bằng (b, a % b), số dư giảm rất nhanh.
  • Khi b = 0, dừng và trả về a — chính là ƯCLN.
💡 Mẹo nhớ: Thuật toán Euclid: "lấy số bé và phần dư, lặp đến khi dư bằng 0, ƯCLN là số còn lại". Dòng a, b = b, a % b gói trọn cả thuật toán.
⚠️ Lưu ý thi: Đề yêu cầu làm theo dạng phép trừ (ƯCLN(a,b)=ƯCLN(b, a−b)) thì nên trình bày Cách 1 cho đúng ý; nhưng nếu được tự do, Cách 2 (phép chia lấy dư) là chuẩn mực và hiệu quả hơn.

🎯 Ghi nhớ: - Dạng "bắt nhập lại cho đúng": dùng while lặp khi dữ liệu còn sai, hoặc while True + break. - In bảng: hai vòng for lồng nhau, dùng end=print() để định dạng. - Năm nhuận: chia hết 4 và không chia hết 100, hoặc chia hết 400. Thế kỉ XXI có 24 năm nhuận. - ƯCLN: thuật toán Euclid — lặp a, b = b, a % b đến khi b = 0.
Chế độ đọc sách →