Buổi 14: Duyệt ước số, Số nguyên tố

Tài liệu tham khảo:

  1. Ước số
  2. Số nguyên tố

Code mẫu:

Kiểm tra SNT

  1. Cách làm "ngây thơ"?:
    C++
    bool is_prime_SLOW(int n) {
        if (n < 2) return false;
        for (int i = 2; i < n; i++)
            if (n%i == 0) return false; // n có ước khác 2 và chính nó
        return true;
    }
    

    Trong Python:
    Python
    def check_prime(n):
        if n < 2: return False
        for i in range(2,n):
            if n % i == 0: return False
        return True
    
  2. Cách làm tối ưu: Ta chỉ sửa giới hạn của vòng lặp for
    Điểm khác biệt là:
    C++
        for (int i = 2; i <= n/i; i++)
    

    Hoặc:
    Python
        for i in range(2, n**0.5 + 1):
    

    Code hoàn chỉnh như sau:
    C++
    bool is_prime(long long n) {
        if (n < 2) return false;
        for (int i = 2; i <= n/i; i++)
            if (n%i == 0) return false;
        return true;
    }
    

    Hoặc:
    Python
    def is_prime(n):
        if n < 2: return False
        for i in range(2, n**0.5 + 1):
            if n % i == 0: return False
        return True
    
Ứng dụng

Ta có thể ứng dụng đoạn code trên để đếm số lượng ước, tính tổng các ước, in ra tất cả ước số, ... tùy yêu cầu đề bài.

Bản chất

Cách làm trên có độ phức tạp \(O(\sqrt{n})\). Vì sao?
Giải thích:
Ví dụ, số \(n = 100\) có các ước \(1,2,4,5,10,20,25,50,100\).
Nếu "cày trâu", vòng lặp for cần chạy qua khoảng \(100\) số.
Tuy nhiên, ta nhận thấy các số đi thành từng cặp:

\[100 = 1\times 100 = 2\times 50 = 4 \times 25 = 5 \times 20 = 10 \times 10\]

Tức là một ước số "bé" sẽ đi với một ước số "lớn". Trong ví dụ trên, giả sử ta đang duyệt for và có \(i = 4\).
n % i == 0 trả về True nên \(i\) chính là một ước của \(100\). Ta lấy \(100 \div 4 = 25\) (100 / i hoặc 100//i), \(25\) chính là "ước số lớn" đi kèm với số \(4\).
Như vậy, ta chỉ cần chạy for tới \(10\) là đã lấy được mọi ước của \(100\)!


Bài tập

Bài tập Điểm Tỷ lệ AC Người nộp
Ước số của n 100 37,6% 4165
Ước số chung 100 50,0% 3419
Ước số và tổng ước số 300p 28,1% 2554
Tổng chẵn 100p 54,2% 4602 Hướng dẫn
Tổng lẻ 100 50,5% 4076



Bình luận

Không có bình luận nào.