Các thuật toán trên dãy

Buổi 10

Python cho Tin học trẻ · Bảng B (THCS)

Buổi 10 – Các thuật toán trên dãy1 / 23

Hôm nay em sẽ học

  1. Tự viết thuật toán tìm lớn nhất / nhỏ nhất và vị trí
  2. Kỹ thuật biến cờ để kiểm tra "mọi phần tử đều …"
  3. Duyệt mọi cặp phần tử
  4. Tìm đoạn liên tiếp dài nhất
Buổi 10 – Các thuật toán trên dãy2 / 23

Khởi động: 10 tấm thẻ úp

Có 10 tấm thẻ úp, mỗi thẻ ghi một số. Em chỉ được nhớ một số trong đầu.

Làm sao tìm được thẻ có số lớn nhất?

Lật từng thẻ. Nếu số trên thẻ lớn hơn số đang nhớ → nhớ số mới. Đó chính là thuật toán tìm max!
Buổi 10 – Các thuật toán trên dãy3 / 23

Phần 1: Tìm lớn nhất

Số đang nhớ – và vị trí của nó
Buổi 10 – Các thuật toán trên dãy4 / 23

Tìm max và vị trí

n = int(input())
a = list(map(int, input().split()))
mx = a[0]
vt = 0
for i in range(1, n):
    if a[i] > mx:
        mx = a[i]
        vt = i
print(mx, vt + 1)
5
4 9 2 9 7
9 2
Không khởi tạo mx = 0 – sẽ sai khi dãy toàn số âm. Hãy khởi tạo bằng a[0].
Buổi 10 – Các thuật toán trên dãy5 / 23

Hàm có sẵn của Python

HàmÝ nghĩa
max(a), min(a)giá trị lớn nhất, nhỏ nhất
sum(a)tổng
a.count(x)số lần x xuất hiện
a.index(x)vị trí đầu tiên của x (đếm từ 0)
Khi đi thi được dùng. Nhưng em phải tự viết được để hiểu và để giải các bài biến thể.
Buổi 10 – Các thuật toán trên dãy6 / 23

Phần 2: Biến cờ

Giả sử đúng – tìm phản ví dụ
Buổi 10 – Các thuật toán trên dãy7 / 23

Dãy có tăng chặt không?

tang = True
for i in range(1, n):
    if a[i] <= a[i - 1]:
        tang = False
        break
print("YES" if tang else "NO")
  1. Giả sử dãy tăng: tang = True
  2. Duyệt tìm phản ví dụ: một chỗ không tăng
  3. Tìm thấy → hạ cờ tang = False
Dùng cho mọi câu hỏi kiểu "tất cả các phần tử có … không?"
Buổi 10 – Các thuật toán trên dãy8 / 23

Phần 3: Duyệt mọi cặp

Hai vòng lặp lồng nhau
Buổi 10 – Các thuật toán trên dãy9 / 23

Đếm cặp có tổng bằng k

dem = 0
for i in range(n):
    for j in range(i + 1, n):
        if a[i] + a[j] == k:
            dem += 1
print(dem)
  • j bắt đầu từ i + 1 để mỗi cặp chỉ đếm một lần
  • Có khoảng n² ÷ 2 cặp
nSố cặpPython
1 000500 000kịp
100 0005 tỷkhông kịp
Buổi 10 – Các thuật toán trên dãy10 / 23

Phần 4: Đoạn liên tiếp

Leo cầu thang
Buổi 10 – Các thuật toán trên dãy11 / 23

Đoạn tăng liên tiếp dài nhất

Dãy: 1 2 5 3 4 6 8 2

a[i]12534682
hien_tai12312341
  • Lớn hơn số trước → bậc thang tiếp tục: hien_tai += 1
  • Không lớn hơn → bắt đầu lại: hien_tai = 1
  • Kết quả là giá trị hien_tai lớn nhất: 4
Buổi 10 – Các thuật toán trên dãy12 / 23

Viết thành code

best = 1
hien_tai = 1
for i in range(1, n):
    if a[i] > a[i - 1]:
        hien_tai += 1
    else:
        hien_tai = 1
    best = max(best, hien_tai)
print(best)
Chỉ duyệt dãy một lần → chạy rất nhanh, kể cả khi n = 10⁵.
Buổi 10 – Các thuật toán trên dãy13 / 23

Luyện tập

Dòng 1 là n (1 ≤ n ≤ 10⁵), dòng 2 là n số nguyên |aᵢ| ≤ 10⁹
Buổi 10 – Các thuật toán trên dãy14 / 23

Bài 1 ★ – MAXMIN

Output: giá trị lớn nhất và nhỏ nhất của dãy.

InputOutput
5 4 -9 2 9 79 -9
Tự viết vòng lặp, không dùng max, min.
Buổi 10 – Các thuật toán trên dãy15 / 23

Bài 2 ★ – VTMAX

Output: tất cả các vị trí (đánh số từ 1) đạt giá trị lớn nhất.

InputOutput
5 4 9 2 9 72 4
Buổi 10 – Các thuật toán trên dãy16 / 23

Bài 3 ★★ – KTTANG

Output: YES nếu dãy tăng chặt (mỗi số lớn hơn số đứng trước), ngược lại NO.

InputOutput
4 1 3 7 10YES
3 1 3 3NO
1 5YES
Buổi 10 – Các thuật toán trên dãy17 / 23

Bài 4 ★★ – CAPTONG

Input: dòng 1 là n (n ≤ 1000) và k; dòng 2 là dãy n số.

Output: số cặp (i < j) có aᵢ + aⱼ = k.

InputOutput
5 6 1 5 3 3 22
Buổi 10 – Các thuật toán trên dãy18 / 23

Bài 5 ★★ – LONNHI

Output: giá trị lớn thứ hai (lớn nhất trong các số nhỏ hơn max), hoặc KHONG nếu không có.

InputOutput
5 4 9 2 9 77
3 5 5 5KHONG
Buổi 10 – Các thuật toán trên dãy19 / 23

Bài 6 ★★★ – DOANTANG

Output: độ dài đoạn con liên tiếp tăng chặt dài nhất.

InputOutput
8 1 2 5 3 4 6 8 24
3 5 4 31
Buổi 10 – Các thuật toán trên dãy20 / 23

Bài 7 ★★★ – DOANTONG

Output: tổng lớn nhất của một đoạn con liên tiếp (có ít nhất một phần tử).

InputOutput
6 -2 3 -1 4 -6 26
3 -5 -2 -8-2
Gợi ý: giống bài 6 – nếu tổng đoạn đang xét bị âm thì bỏ đi, bắt đầu lại.
Buổi 10 – Các thuật toán trên dãy21 / 23

Tóm tắt buổi 10

Kỹ thuậtÝ tưởng
Tìm maxnhớ số lớn nhất, gặp số lớn hơn thì thay
Biến cờgiả sử đúng, tìm phản ví dụ
Duyệt cặpfor i … for j in range(i + 1, n) – chỉ khi n nhỏ
Đoạn liên tiếptiếp tục hoặc bắt đầu lại
Buổi 10 – Các thuật toán trên dãy22 / 23

Bài về nhà

  1. Đếm số đỉnh của dãy: aᵢ lớn hơn cả hai phần tử kề bên (1 < i < n).
  2. Độ dài đoạn dài nhất gồm các phần tử bằng nhau liên tiếp.
  3. Dãy có phải cấp số cộng không? (hiệu hai số liên tiếp luôn bằng nhau)
Buổi 10 – Các thuật toán trên dãy23 / 23
← → chuyển slide · F toàn màn hình