Trắc nghiệm Tin học 11 Kết nối tri thức Bài 24: Đánh giá độ phức tạp thời gian thuật toán - Đề 02
Trắc nghiệm Tin học 11 Kết nối tri thức Bài 24: Đánh giá độ phức tạp thời gian thuật toán - Đề 02 được xây dựng với nhiều câu hỏi chất lượng, sát với nội dung chương trình học, giúp bạn dễ dàng ôn tập và kiểm tra kiến thức hiệu quả. Hãy cùng bắt đầu làm bài tập trắc nghiệm ngay để nâng cao hiểu biết và chuẩn bị tốt cho kỳ thi sắp tới!
Câu 1: Khi phân tích độ phức tạp thời gian của một thuật toán, tại sao chúng ta thường chỉ quan tâm đến số lượng các phép toán cơ bản (như gán, so sánh, cộng, trừ) thay vì thời gian thực thi chính xác trên một máy tính cụ thể?
- A. Thời gian thực thi chính xác quá khó để đo lường.
- B. Các phép toán cơ bản luôn mất cùng một lượng thời gian trên mọi máy tính.
- C. Chỉ có các phép toán cơ bản mới ảnh hưởng đến hiệu suất thuật toán.
- D. Số lượng phép toán cơ bản cung cấp ước lượng hiệu suất độc lập với phần cứng và môi trường thực thi.
Câu 2: Độ phức tạp thời gian O(n) mô tả mối quan hệ giữa thời gian thực thi và kích thước đầu vào n như thế nào?
- A. Thời gian thực thi không đổi khi n tăng.
- B. Thời gian thực thi tăng tỷ lệ thuận (tuyến tính) với n.
- C. Thời gian thực thi tăng theo hàm bình phương của n.
- D. Thời gian thực thi tăng theo hàm logarit của n.
Câu 3: Cho đoạn mã giả sau:
```
function process(arr, n):
sum = 0
for i from 0 to n-1:
sum = sum + arr[i]
return sum
```
Độ phức tạp thời gian của đoạn mã này là bao nhiêu, với n là kích thước của mảng `arr`?
- A. O(1)
- B. O(log n)
- C. O(n)
- D. O(n^2)
Câu 4: Cho đoạn mã giả sau:
```
function find_max(arr, n):
max_val = arr[0]
for i from 1 to n-1:
if arr[i] > max_val:
max_val = arr[i]
return max_val
```
Độ phức tạp thời gian của đoạn mã này trong trường hợp xấu nhất (worst-case) là bao nhiêu, với n là kích thước của mảng `arr`?
- A. O(1)
- B. O(log n)
- C. O(n)
- D. O(n log n)
Câu 5: Thuật toán tìm kiếm nhị phân trên một mảng đã được sắp xếp có độ phức tạp thời gian là O(log n). Điều này có nghĩa là gì?
- A. Thời gian tìm kiếm tăng gấp đôi khi kích thước mảng tăng gấp đôi.
- B. Thời gian tìm kiếm giảm đi một nửa khi kích thước mảng tăng gấp đôi.
- C. Thời gian tìm kiếm tăng theo bình phương của kích thước mảng.
- D. Thời gian tìm kiếm tăng rất chậm khi kích thước mảng tăng lên đáng kể.
Câu 6: Cho đoạn mã giả sau:
```
function print_pairs(arr, n):
for i from 0 to n-1:
for j from 0 to n-1:
print(arr[i], arr[j])
```
Độ phức tạp thời gian của đoạn mã này là bao nhiêu, với n là kích thước của mảng `arr`?
- A. O(n)
- B. O(n log n)
- C. O(log n)
- D. O(n^2)
Câu 7: Khi so sánh hai thuật toán A có độ phức tạp O(n) và thuật toán B có độ phức tạp O(n^2) để giải cùng một bài toán với kích thước đầu vào n rất lớn, thuật toán nào thường được ưu tiên hơn và vì sao?
- A. Thuật toán A (O(n)) vì thời gian thực thi tăng chậm hơn nhiều so với O(n^2) khi n lớn.
- B. Thuật toán B (O(n^2)) vì nó có thể xử lý dữ liệu lớn hơn.
- C. Cả hai thuật toán đều có hiệu quả như nhau với n lớn.
- D. Không thể xác định chỉ dựa vào độ phức tạp Big O.
Câu 8: Quy tắc cộng trong phân tích độ phức tạp thời gian được áp dụng khi nào?
- A. Khi các khối lệnh hoặc hàm được thực thi nối tiếp nhau.
- B. Khi có các vòng lặp lồng nhau.
- C. Khi các khối lệnh hoặc hàm được thực thi song song.
- D. Khi kích thước đầu vào được chia nhỏ.
Câu 9: Quy tắc nhân trong phân tích độ phức tạp thời gian được áp dụng khi nào?
- A. Khi các khối lệnh được thực thi nối tiếp nhau.
- B. Khi một khối lệnh (hoặc vòng lặp) được thực hiện bên trong một cấu trúc lặp khác.
- C. Khi thuật toán sử dụng phép nhân số học.
- D. Khi kết hợp độ phức tạp của hai thuật toán khác nhau.
Câu 10: Cho đoạn mã giả sau:
```
function example(n):
for i from 1 to 100:
print(i)
for j from 1 to n:
print(j)
```
Độ phức tạp thời gian của đoạn mã này là bao nhiêu?
- A. O(1)
- B. O(100)
- C. O(n)
- D. O(100n)
Câu 11: Thuật toán nào sau đây thường có độ phức tạp thời gian tốt nhất (hiệu quả nhất) khi kích thước đầu vào n rất lớn?
- A. O(1)
- B. O(log n)
- C. O(n)
- D. O(n log n)
Câu 12: Độ phức tạp thời gian O(n^2) thường xuất hiện trong các thuật toán có cấu trúc như thế nào?
- A. Chỉ có các phép toán cơ bản.
- B. Một vòng lặp đơn chạy n lần.
- C. Hai vòng lặp lồng nhau, mỗi vòng lặp chạy khoảng n lần.
- D. Sử dụng đệ quy chia đôi.
Câu 13: Tại sao các hằng số và các thành phần bậc thấp thường bị bỏ qua trong ký hiệu Big O?
- A. Chúng không ảnh hưởng đến thời gian thực thi.
- B. Khi n rất lớn, thành phần bậc cao nhất chi phối sự tăng trưởng của hàm thời gian.
- C. Việc tính toán chúng rất phức tạp.
- D. Chúng chỉ quan trọng trong trường hợp tốt nhất.
Câu 14: Cho đoạn mã giả sau:
```
function example(arr, n):
if n <= 1:
return
// Chia mảng làm đôi
mid = n / 2
left_half = arr[0...mid-1]
right_half = arr[mid...n-1]
// Gọi đệ quy trên hai nửa
example(left_half, mid)
example(right_half, n - mid)
// Các thao tác kết hợp (ví dụ: trộn mảng đã sắp xếp)
// ... (thực hiện trong thời gian O(n))
```
Đây là cấu trúc của một thuật toán "chia để trị" điển hình (ví dụ: Merge Sort). Độ phức tạp thời gian của các thuật toán dạng này thường là bao nhiêu?
- A. O(n^2)
- B. O(n)
- C. O(log n)
- D. O(n log n)
Câu 15: Tại sao việc đánh giá độ phức tạp thời gian (và không gian) của thuật toán lại quan trọng trong việc phát triển phần mềm?
- A. Giúp dự đoán hiệu suất của chương trình với các bộ dữ liệu đầu vào lớn và so sánh hiệu quả giữa các thuật toán khác nhau.
- B. Chỉ cần thiết khi lập trình trên các hệ thống nhúng với bộ nhớ hạn chế.
- C. Là yêu cầu bắt buộc của mọi ngôn ngữ lập trình hiện đại.
- D. Chỉ giúp tìm ra lỗi logic trong mã nguồn.
Câu 16: Cho đoạn mã giả:
```
function example(n):
i = 1
while i < n:
print(i)
i = i * 2
```
Độ phức tạp thời gian của đoạn mã này là bao nhiêu?
- A. O(n)
- B. O(log n)
- C. O(n^2)
- D. O(1)
Câu 17: Thuật toán nào dưới đây, khi triển khai một cách cơ bản, thường có độ phức tạp thời gian là O(n^2)?
- A. Sắp xếp chọn (Selection Sort)
- B. Tìm kiếm nhị phân (Binary Search)
- C. Sắp xếp trộn (Merge Sort)
- D. Sắp xếp nhanh (Quick Sort) - trung bình
Câu 18: Giả sử một thuật toán có độ phức tạp thời gian là T(n) = 5n^2 + 3n + 10. Khi sử dụng ký hiệu Big O để biểu diễn độ phức tạp, kết quả đúng là gì?
- A. O(n)
- B. O(5n^2)
- C. O(n^2 + n)
- D. O(n^2)
Câu 19: Trường hợp tốt nhất (best-case) của một thuật toán là gì?
- A. Bộ dữ liệu đầu vào làm cho thuật toán thực thi với thời gian ngắn nhất.
- B. Bộ dữ liệu đầu vào làm cho thuật toán thực thi với thời gian dài nhất.
- C. Bộ dữ liệu đầu vào trung bình.
- D. Trường hợp thuật toán không có lỗi.
Câu 20: Trường hợp xấu nhất (worst-case) của một thuật toán là gì?
- A. Bộ dữ liệu đầu vào làm cho thuật toán thực thi với thời gian ngắn nhất.
- B. Bộ dữ liệu đầu vào làm cho thuật toán thực thi với thời gian dài nhất.
- C. Bộ dữ liệu đầu vào trung bình.
- D. Trường hợp thuật toán hoạt động chính xác.
Câu 21: Cho đoạn mã giả:
```
function example(n):
sum = 0
for i from 1 to n:
sum = sum + i
j = 1
while j < n:
print(j)
j = j * 3
```
Độ phức tạp thời gian của đoạn mã này là bao nhiêu?
- A. O(log n)
- B. O(n log n)
- C. O(n)
- D. O(n + log n)
Câu 22: Thuật toán tìm kiếm tuyến tính (Linear Search) trên một mảng có n phần tử có độ phức tạp thời gian trong trường hợp xấu nhất là bao nhiêu?
- A. O(1)
- B. O(log n)
- C. O(n)
- D. O(n^2)
Câu 23: Độ phức tạp thời gian O(1) có nghĩa là gì?
- A. Thời gian thực thi không thay đổi khi kích thước đầu vào n thay đổi.
- B. Thời gian thực thi tăng tuyến tính với n.
- C. Thời gian thực thi là 1 đơn vị.
- D. Thuật toán rất nhanh.
Câu 24: Cho đoạn mã giả:
```
function example(n):
for i from 1 to n:
for j from 1 to i:
print(i, j)
```
Độ phức tạp thời gian của đoạn mã này là bao nhiêu?
- A. O(n)
- B. O(n log n)
- C. O(log n)
- D. O(n^2)
Câu 25: Khi phân tích độ phức tạp thời gian của thuật toán, "kích thước đầu vào" (input size) n thường được định nghĩa là gì?
- A. Số dòng mã lệnh của chương trình.
- B. Một tham số đo lường quy mô của dữ liệu mà thuật toán xử lý (ví dụ: số phần tử, số bit).
- C. Thời gian chạy thực tế của chương trình.
- D. Số lượng biến được sử dụng trong thuật toán.
Câu 26: Giả sử bạn có hai thuật toán để giải quyết một bài toán: Thuật toán X có độ phức tạp O(n log n) và Thuật toán Y có độ phức tạp O(n^2). Với n = 1000, thuật toán nào có khả năng chạy nhanh hơn và tại sao?
- A. Thuật toán X (O(n log n)) vì n log n tăng chậm hơn nhiều so với n^2 khi n lớn.
- B. Thuật toán Y (O(n^2)) vì n^2 lớn hơn n log n.
- C. Cả hai thuật toán sẽ chạy với tốc độ tương đương nhau.
- D. Không thể xác định nếu không biết hằng số ẩn trong ký hiệu Big O.
Câu 27: Thuật toán sắp xếp nào dưới đây, khi triển khai hiệu quả, có độ phức tạp thời gian trung bình là O(n log n)?
- A. Sắp xếp chèn (Insertion Sort)
- B. Sắp xếp trộn (Merge Sort)
- C. Sắp xếp nổi bọt (Bubble Sort)
- D. Sắp xếp chọn (Selection Sort)
Câu 28: Nếu một thuật toán có độ phức tạp thời gian là O(2^n), điều gì sẽ xảy ra với thời gian thực thi khi kích thước đầu vào n tăng lên một lượng nhỏ (ví dụ: tăng thêm 1 hoặc 2)?
- A. Thời gian thực thi tăng tuyến tính.
- B. Thời gian thực thi tăng logarit.
- C. Thời gian thực thi tăng theo bình phương.
- D. Thời gian thực thi tăng theo cấp số nhân (rất nhanh).
Câu 29: Cho đoạn mã giả:
```
function example(arr, n):
if n <= 0:
return 0
if n == 1:
return arr[0]
// Giả sử hàm sum_array_recursive(arr, n) tính tổng n phần tử
// bằng cách gọi đệ quy trên n-1 phần tử và cộng thêm phần tử cuối.
// Độ phức tạp của hàm này là O(n).
return sum_array_recursive(arr, n)
```
Độ phức tạp thời gian của hàm `example` gọi `sum_array_recursive` như mô tả là bao nhiêu?
- A. O(1)
- B. O(log n)
- C. O(n)
- D. O(n^2)
Câu 30: Khi so sánh hiệu quả của hai thuật toán A (O(n log n)) và B (O(n^2)) cho một bài toán, có trường hợp nào mà thuật toán B có thể chạy nhanh hơn thuật toán A không?
- A. Không bao giờ, vì O(n log n) luôn tốt hơn O(n^2).
- B. Có thể, khi kích thước đầu vào n rất nhỏ, hằng số ẩn trong ký hiệu Big O có thể làm thay đổi kết quả so sánh.
- C. Có thể, nhưng chỉ trong trường hợp tốt nhất của thuật toán B.
- D. Chỉ khi thuật toán B được viết bằng ngôn ngữ lập trình nhanh hơn.