Buổi 10: Các thuật toán trên dãy
Hôm nay em sẽ học
- Tự viết thuật toán tìm lớn nhất / nhỏ nhất và vị trí
- Kỹ thuật biến cờ để kiểm tra "mọi phần tử đều …"
- Duyệt mọi cặp phần tử
- Tìm đoạn liên tiếp dài nhất
Bấm vào slide rồi dùng phím ← → để chuyển, phím F để xem toàn màn hình.
Mở toàn màn hình1. Kiến thức chính
Tìm lớn nhất và vị trí
mx = a[0] # KHÔNG khởi tạo mx = 0 (sai khi dãy toàn số âm) vt = 0 for i in range(1, n): if a[i] > mx: mx = a[i] vt = i print(mx, vt + 1) # vị trí đánh số từ 1
Hàm có sẵn được dùng khi đi thi: max(a), min(a), sum(a), a.count(x), a.index(x).
Biến cờ – kiểm tra "mọi phần tử đều …"
tang = True # 1. giả sử dãy tăng for i in range(1, n): if a[i] <= a[i - 1]: # 2. tìm phản ví dụ tang = False # 3. hạ cờ break
Duyệt mọi cặp (i < j)
for i in range(n): for j in range(i + 1, n): # j bắt đầu từ i + 1: mỗi cặp xét một lần ...
Có khoảng n² ÷ 2 cặp: n = 1000 thì kịp, n = 10⁵ thì không kịp.
Đoạn liên tiếp dài nhất
best = hien_tai = 1 for i in range(1, n): if a[i] > a[i - 1]: hien_tai += 1 # bậc thang tiếp tục else: hien_tai = 1 # bắt đầu lại best = max(best, hien_tai)
Chỉ duyệt dãy một lần nên chạy nhanh kể cả khi n = 10⁵.
2. Ghi nhớ và lỗi thường gặp
| Lỗi | Hậu quả |
|---|---|
Khởi tạo mx = 0 | sai khi dãy toàn số âm |
So sánh a[i] với a[i - 1] khi i = 0 | a[-1] là phần tử cuối – kết quả sai mà không báo lỗi |
Quên cập nhật best ở phần tử cuối | sai khi đoạn dài nhất nằm ở cuối dãy |
| Duyệt cặp khi n = 10⁵ | quá thời gian |
3. Câu hỏi tự kiểm tra
- Vì sao khởi tạo
mx = a[0]tốt hơnmx = 0? - Với n = 5, hai vòng lặp
for i in range(n)vàfor j in range(i + 1, n)xét tất cả bao nhiêu cặp? - Trong dãy 4 4 4, đoạn tăng chặt liên tiếp dài nhất có độ dài bao nhiêu?
4. Bài tập về nhà
Định dạng input chung (trừ khi ghi khác): dòng 1 là n (1 ≤ n ≤ 10⁵), dòng 2 là n số nguyên (|aᵢ| ≤ 10⁹).
Bài 1 ★★ – DEMDINH
Phần tử aᵢ (không phải đầu dãy, không phải cuối dãy) là đỉnh nếu nó lớn hơn cả hai phần tử kề bên.
Output: số đỉnh của dãy.
| Input | Output |
|---|---|
71 3 2 5 4 4 6 | 2 |
Bài 2 ★★ – DOANBANG
Output: độ dài đoạn dài nhất gồm các phần tử bằng nhau đứng liên tiếp.
| Input | Output |
|---|---|
81 1 2 2 2 3 2 2 | 3 |
Bài 3 ★★ – CAPSOCONG
Dãy là cấp số cộng nếu hiệu hai số liên tiếp luôn bằng nhau (ví dụ 2 5 8 11).
Output: YES hoặc NO.
| Input | Output |
|---|---|
42 5 8 11 | YES |
31 2 4 | NO |
Bài 4 ★★★ (thử thách) – LAINHAT
aᵢ là giá một món hàng vào ngày thứ i. Em mua vào một ngày và bán ra vào một ngày sau đó. Tìm tiền lãi lớn nhất (có thể âm nếu ngày nào cũng lỗ).
Input: như trên với n ≥ 2. Output: lãi lớn nhất = max(aⱼ − aᵢ) với i < j.
| Input | Output |
|---|---|
67 1 5 3 6 4 | 5 |
35 4 1 | -1 |
.py đặt tên theo tên bài. Chạy thử với tất cả ví dụ trước khi nộp!Chưa mở đáp án
Đáp án sẽ được mở sau khi các em nộp bài tập về nhà.
Chưa mở đáp án
Đáp án sẽ được mở sau khi các em nộp bài tập về nhà.