Hướng dẫn giải của Dãy có giá trị trung bình lớn nhất


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Lời giải này đang bị ẩn cho đến khi bạn chọn mở ra.

Chúng tôi khuyên bạn nên tự thử giải bài trước. Việc mở lời giải có thể làm lộ mất ý tưởng chính trước khi bạn có cơ hội tự giải.

Bạn phải đăng nhập để mở lời giải này.

Đăng nhập

Tác giả: Hiếu Nguyễn, 111_LeQuangTam, Nguyenhoang150908, hung8989

Hiểu bài toán

Bài toán yêu cầu tìm độ dài dãy con liên tiếp có giá trị trung bình lớn nhất. Tuy nhiên, dựa trên các giải pháp đã nộp, có thể thấy giá trị trung bình lớn nhất của một dãy con chỉ có thể đạt được khi tất cả các phần tử trong dãy con đó bằng nhau và bằng giá trị lớn nhất trong toàn bộ dãy. Nếu một dãy con chứa bất kỳ phần tử nào nhỏ hơn giá trị lớn nhất, giá trị trung bình của dãy con đó sẽ nhỏ hơn giá trị lớn nhất. Do đó, bài toán quy về việc tìm dãy con liên tiếp dài nhất mà tất cả các phần tử đều bằng giá trị lớn nhất của toàn mảng.

Các cách tiếp cận

Cách Brute Force (Duyệt tất cả các dãy con)
#include <iostream>
#include <vector>
#include <limits>
using namespace std;

int main() {
    int N;
    cin >> N;
    vector<long long> a(N);
    long long mx = -1e18;
    for (int i = 0; i < N; i++) {
        cin >> a[i];
        if (a[i] > mx) mx = a[i];
    }

    int maxLen = 0;
    // Duyệt tất cả các dãy con
    for (int i = 0; i < N; i++) {
        long long sum = 0;
        for (int j = i; j < N; j++) {
            sum += a[j];
            int len = j - i + 1;
            // Kiểm tra điều kiện trung bình == max
            if (sum == mx * len) {
                if (len > maxLen) maxLen = len;
            }
        }
    }
    cout << maxLen;
    return 0;
}
  • Time Complexity: O(N^2)
  • Space Complexity: O(N)

Cách tiếp cận này thử tất cả các dãy con con có thể có (từ i đến j). Với mỗi dãy con, nó tính tổng và kiểm tra xem trung bình của dãy con đó có bằng giá trị lớn nhất của toàn mảng hay không. Nếu bằng thì cập nhật độ dài lớn nhất. Phương pháp này đúng nhưng quá chậm cho dữ liệu lớn.

Cách Duyệt tối ưu dựa trên tính chất toán học
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    // Tối ưu tốc độ nhập xuất
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    freopen("average.inp", "r", stdin);
    freopen("average.out", "w", stdout);

    int N;
    cin >> N;
    vector<long long> a(N);

    // Tìm giá trị lớn nhất trong mảng
    long long mx = -1e18;
    for (int i = 0; i < N; i++) {
        cin >> a[i];
        if (a[i] > mx) mx = a[i];
    }

    // Duyệt một lần để tìm dãy liên tiếp các số bằng mx có độ dài lớn nhất
    int maxLen = 0;
    int currentLen = 0;
    for (int i = 0; i < N; i++) {
        if (a[i] == mx) {
            currentLen++;
            if (currentLen > maxLen) maxLen = currentLen;
        } else {
            currentLen = 0;
        }
    }

    cout << maxLen;
    return 0;
}
  • Time Complexity: O(N)
  • Space Complexity: O(N)

Đây là giải pháp tối ưu. Ta nhận thấy rằng để trung bình một dãy con bằng giá trị lớn nhất (mx), tất cả các phần tử trong dãy con đó phải bằng mx. Nếu có bất kỳ phần tử nào nhỏ hơn mx, trung bình sẽ giảm. Do đó, bài toán chỉ cần tìm dãy con liên tiếp dài nhất mà mọi phần tử đều bằng mx. Ta duyệt qua mảng một lần, đếm độ dài dãy liên tiếp các số bằng mx và cập nhật độ dài lớn nhất.

Phân tích độ phức tạp

Cách tiếp cận Time Space Tên
1 O(N^2) O(N) Brute Force (Duyệt tất cả các dãy con)
2 O(N) O(N) Duyệt tối ưu dựa trên tính chất toán học

Bài học kinh nghiệm

  • Giá trị trung bình lớn nhất của một dãy con bất kỳ không thể vượt quá giá trị lớn nhất của các phần tử trong dãy gốc (Max).
  • Để một dãy con có giá trị trung bình bằng Max, tất cả các phần tử trong dãy con đó phải bằng Max.

Lỗi thường gặp

  • Sử dụng biến kiểu int để lưu tổng hoặc giá trị lớn nhất có thể gây tràn số (overflow) nếu giá trị phần tử lớn.
  • Quên xử lý trường hợp mảng rỗng hoặc kết quả trả về.

Bình luận

Please read the guidelines before commenting.


Không có bình luận tại thời điểm này.