Giải Tin Học 10 trang 140
Lời giải chi tiết SGK Lớp 10 · Môn Tin Há»c · Trang 140–141
Nguon: Tin Hoc 10 - Ket Noi Tri Thuc Voi Cuoc Song (trang 140 – 141)
🔍 Kiến thức cần nhớ
Bài này tiếp tục chủ đề Hàm trong Python. Các điểm trọng tâm:
- Một hàm được định nghĩa bằng từ khóa
def, có thể nhận tham số đầu vào và trả kết quả qua lệnhreturn. - Một chương trình lớn nên chia thành nhiều hàm nhỏ, mỗi hàm làm một việc (gọi là kĩ thuật mô-đun hóa). Cách này giúp chương trình dễ đọc, dễ kiểm thử, dễ sửa lỗi.
- Các lệnh xử lí xâu hữu ích:
Str.upper()– chuyển toàn bộ kí tự thành chữ in hoa.Str.lower()– chuyển toàn bộ kí tự thành chữ in thường.Str.title()– viết hoa kí tự đầu mỗi từ, các kí tự khác về chữ thường.Str.split()– tách xâu thành danh sách các từ (mặc định tách theo dấu cách).- Phương thức
list.append(x)– thêm phần tửxvào cuối danh sách.
💡 Mẹo nhớ: Muốn lấy phần tử thỏa điều kiện từ danh sách A → tạo danh sách rỗng[]rồi duyệt từng phần tử, gặp phần tử thỏa điều kiện thìappend()vào.
⚙️ Bài tập
Nhiệm vụ 3 (phân tích chương trình mẫu)
Đề bài: Viết chương trình thực hiện lần lượt:
- Nhập một dãy số nguyên cách nhau bởi dấu cách, đưa vào danh sách A và in ra.
- Trích từ A danh sách B gồm các phần tử lớn hơn 0, in ra.
- Trích từ A danh sách C gồm các phần tử nhỏ hơn 0, in ra.
Yêu cầu: mỗi việc viết thành một hàm riêng.
Cách 1 — Mô-đun hóa theo sách giáo khoa
def Nhap_Dulieu():
s = input("Nhập các số nguyên cách nhau bởi dấu cách: ")
A = s.split() # tách xâu thành danh sách các từ
for k in range(len(A)):
A[k] = int(A[k]) # đổi từng phần tử về kiểu số nguyên
return A
def getB(A):
B = []
for x in A:
if x > 0:
B.append(x)
return B
def getC(A):
C = []
for x in A:
if x < 0:
C.append(x)
return C
# Chương trình chính
A = Nhap_Dulieu()
print("Danh sách A:", A)
B = getB(A)
C = getC(A)
print("Danh sách B:", B)
print("Danh sách C:", C)
Giải thích từng bước:
Nhap_Dulieu(): nhập xâu, dùngsplit()để tách thành danh sách các từ (lúc này mỗi phần tử vẫn là xâu kí tự), rồi dùng vòngforđổi từng phần tử sang số nguyên bằngint().getB(A): duyệt từng phần tửxtrong A, nếux > 0thì thêm vào B.getC(A): tương tự nhưng lấy các phần tửx < 0.
Ví dụ chạy thử: nhập 3 -5 0 8 -2 1
Danh sách A: [3, -5, 0, 8, -2, 1]
Danh sách B: [3, 8, 1]
Danh sách C: [-5, -2]
⚠️ Lưu ý thi: Số 0 không vào B (vì điều kiện là> 0) cũng không vào C (vì< 0). Đề thi hay gài bẫy ở phần tử bằng 0.
Cách 2 — Dùng list comprehension (ngắn gọn)
def getB(A):
return [x for x in A if x > 0]
def getC(A):
return [x for x in A if x < 0]
Cách viết này cho kết quả giống hệt Cách 1 nhưng gọn hơn, rất hay dùng trong Python.
LUYỆN TẬP
Câu 1
Đề bài: Viết hàm có:
- Đầu vào là danh sách
sList, các phần tử là xâu kí tự. - Đầu ra là danh sách
cList, các phần tử là kí tự đầu tiên của các xâu tương ứng trongsList.
Cách 1 — Dùng vòng lặp cơ bản
def Lay_kitu_dau(sList):
cList = []
for s in sList:
cList.append(s[0]) # s[0] là kí tự đầu tiên của xâu s
return cList
# Kiểm thử
sList = ["Ha Noi", "Hue", "Sai Gon"]
print(Lay_kitu_dau(sList)) # ['H', 'H', 'S']
Giải thích: Với mỗi xâu s, kí tự đầu tiên có chỉ số 0, lấy bằng s[0], rồi thêm vào cList.
Cách 2 — Dùng list comprehension
def Lay_kitu_dau(sList):
return [s[0] for s in sList]
⚠️ Lưu ý thi: Nếu trongsListcó xâu rỗng""thìs[0]sẽ báo lỗi. Để an toàn có thể kiểm traif len(s) > 0trước khi lấy kí tự đầu.
Câu 2
Đề bài: Viết hàm Tach_day() với đầu vào là danh sách A, đầu ra là hai danh sách B, C:
- B thu được từ A bằng cách lấy các phần tử có chỉ số chẵn.
- C thu được từ A bằng cách lấy các phần tử có chỉ số lẻ.
📌 Sách in nhầm dòng thứ hai là "Danh sách B"; đúng phải là danh sách C – các phần tử có chỉ số lẻ.
Cách 1 — Duyệt chỉ số và kiểm tra chẵn/lẻ
def Tach_day(A):
B = []
C = []
for k in range(len(A)):
if k % 2 == 0: # chỉ số chẵn: 0, 2, 4, ...
B.append(A[k])
else: # chỉ số lẻ: 1, 3, 5, ...
C.append(A[k])
return B, C
# Kiểm thử
A = [10, 20, 30, 40, 50]
B, C = Tach_day(A)
print("B (chỉ số chẵn):", B) # [10, 30, 50]
print("C (chỉ số lẻ):", C) # [20, 40]
Giải thích: Phép k % 2 cho số dư khi chia k cho 2. Dư 0 ⇒ chỉ số chẵn ⇒ vào B; dư 1 ⇒ chỉ số lẻ ⇒ vào C. Hàm trả về đồng thời hai danh sách qua return B, C.
Cách 2 — Dùng phép cắt (slicing) của Python
def Tach_day(A):
B = A[0::2] # bắt đầu từ 0, bước nhảy 2 → các chỉ số chẵn
C = A[1::2] # bắt đầu từ 1, bước nhảy 2 → các chỉ số lẻ
return B, C
💡 Mẹo nhớ: Cú phápA[start::step]. VớiA[0::2]lấy phần tử chỉ số 0, 2, 4...;A[1::2]lấy chỉ số 1, 3, 5... Đây là cách "thần tốc" để tách dãy theo chẵn/lẻ.
⚠️ Lưu ý: Đừng nhầm chỉ số chẵn (vị trí 0, 2, 4...) với giá trị chẵn (số chia hết cho 2). Đề yêu cầu theo chỉ số.
VẬN DỤNG
Câu 1
Đề bài: Viết hàm có hai tham số m, n. Đầu ra trả lại hai giá trị:
- ƯCLN (ước chung lớn nhất) của m, n.
- BCNN (bội chung nhỏ nhất) của m, n.
Gợi ý: dùng công thức ƯCLN(m, n) × BCNN(m, n) = m × n.
Cách 1 — Thuật toán Euclid (trừ liên tiếp / chia lấy dư)
def UCLN_BCNN(m, n):
a, b = m, n
while b != 0: # thuật toán Euclid bằng phép chia lấy dư
a, b = b, a % b
ucln = a
bcnn = m * n // ucln # suy ra từ công thức gợi ý
return ucln, bcnn
# Kiểm thử
print(UCLN_BCNN(12, 18)) # (6, 36)
Giải thích thuật toán Euclid:
- Lặp lại phép thay
a, b = b, a % bcho đến khib = 0. - Khi đó
achính là ƯCLN của m và n. - Áp dụng công thức gợi ý: BCNN = (m × n) ÷ ƯCLN. Dùng phép chia lấy phần nguyên
//để kết quả là số nguyên.
Kiểm tra với 12 và 18: ƯCLN = 6; BCNN = 12 × 18 ÷ 6 = 216 ÷ 6 = 36. ✓
Cách 2 — Thuật toán Euclid bằng phép trừ (gần với cách lớp dưới)
def UCLN_BCNN(m, n):
a, b = m, n
while a != b:
if a > b:
a = a - b
else:
b = b - a
ucln = a # khi a = b thì đó là ƯCLN
bcnn = m * n // ucln
return ucln, bcnn
💡 Mẹo nhớ: ƯCLN × BCNN = tích hai số. Nhớ tìm ƯCLN trước, BCNN suy ra ngay từ công thức.
⚠️ Lưu ý thi: Dùng//(chia lấy nguyên) chứ không dùng/(chia thực, cho số thực có phần thập phân). Đây là lỗi rất hay gặp.
Câu 2
Đề bài: Viết chương trình nhập ba số tự nhiên day, month, year (cách nhau bởi dấu cách) biểu diễn ngày, tháng, năm. Chương trình kiểm tra và in ra thông báo dữ liệu nhập vào có hợp lệ hay không.
Cách 1 — Kiểm tra đầy đủ từng điều kiện
def la_nam_nhuan(year):
# Năm nhuận: chia hết cho 4 và (không chia hết cho 100 hoặc chia hết cho 400)
if year % 4 == 0 and (year % 100 != 0 or year % 400 == 0):
return True
return False
def kiem_tra_ngay(day, month, year):
# Kiểm tra tháng hợp lệ
if month < 1 or month > 12:
return False
# Số ngày tối đa của mỗi tháng
so_ngay = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
# Điều chỉnh tháng 2 nếu năm nhuận
if la_nam_nhuan(year):
so_ngay[1] = 29
# Kiểm tra ngày hợp lệ
if day < 1 or day > so_ngay[month - 1]:
return False
return True
# Chương trình chính
s = input("Nhập ngày tháng năm (cách nhau bởi dấu cách): ")
day, month, year = s.split()
day = int(day)
month = int(month)
year = int(year)
if kiem_tra_ngay(day, month, year):
print("Số liệu đã nhập là HỢP LỆ.")
else:
print("Số liệu đã nhập KHÔNG hợp lệ.")
Giải thích các bước kiểm tra:
- Tháng phải nằm trong khoảng 1 đến 12.
- Dùng danh sách
so_ngaylưu số ngày tối đa của 12 tháng (chỉ số 0 là tháng 1, ..., chỉ số 11 là tháng 12). - Năm nhuận: tháng 2 có 29 ngày khi năm chia hết cho 4 và (không chia hết cho 100 hoặc chia hết cho 400). Ví dụ: 2000 nhuận, 1900 không nhuận, 2024 nhuận.
- Ngày phải từ 1 đến số ngày tối đa của tháng đó (
so_ngay[month - 1], trừ 1 vì chỉ số danh sách bắt đầu từ 0).
Ví dụ chạy thử:
- Nhập
29 2 2024→ HỢP LỆ (2024 là năm nhuận). - Nhập
29 2 2023→ KHÔNG hợp lệ (2023 không nhuận, tháng 2 chỉ có 28 ngày). - Nhập
31 4 2025→ KHÔNG hợp lệ (tháng 4 chỉ có 30 ngày).
Cách 2 — Dùng thư viện datetime (gọn, chuẩn xác)
import datetime
s = input("Nhập ngày tháng năm (cách nhau bởi dấu cách): ")
day, month, year = map(int, s.split())
try:
datetime.date(year, month, day) # nếu ngày sai sẽ sinh lỗi
print("Số liệu đã nhập là HỢP LỆ.")
except ValueError:
print("Số liệu đã nhập KHÔNG hợp lệ.")
Giải thích: Thư viện datetime tự kiểm tra tính hợp lệ của ngày (kể cả năm nhuận). Nếu ngày không tồn tại, lệnh tạo date sẽ sinh lỗi ValueError, ta bắt lỗi bằng try ... except.
💡 Mẹo nhớ năm nhuận: "Chia hết cho 4 → nhuận, nhưng chia hết cho 100 → không nhuận, trừ khi chia hết cho 400 → lại nhuận." Vì vậy 1900 không nhuận còn 2000 nhuận.
⚠️ Lưu ý thi: map(int, s.split()) là cách chuyển nhanh nhiều xâu thành số nguyên trong một dòng. Đề thi rất ưa câu kiểm tra ngày tháng năm vì gộp được nhiều kĩ năng: nhập dữ liệu, dùng hàm, điều kiện lồng nhau và năm nhuận.
🎯 Ghi nhớ: - Chia chương trình thành các hàm nhỏ, mỗi hàm một nhiệm vụ → dễ đọc, dễ sửa. -s[0]lấy kí tự đầu;A[0::2]/A[1::2]tách theo chỉ số chẵn/lẻ. - ƯCLN dùng thuật toán Euclid; suy ra BCNN bằng công thức ƯCLN × BCNN = m × n. - Kiểm tra ngày hợp lệ phải xét tháng, số ngày từng tháng và năm nhuận.
