Editorial for Tìm cặp số


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.

Submitting an official solution before solving the problem yourself is a bannable offence.

\(\color{red}{\text{Spoiler Alert}_{{}_{{}^{{}^{v2.99}}}}}\)


\(\color{#008b8b}{\text{Hướng dẫn}}\)

  • Với mỗi vị trí \(l\) thỏa \((1 \leq l < n)\), tìm vị trí lớn nhất \(r\) thỏa \((l < r \leq n)\) sao cho \(a_l + a_r \leq X\)

  • Nếu tồn tại một vị trí \(l\) sao cho tìm được vị trí \(r\)\(a_l + a_r = X\) thì xuất \(l\)\(r\) và dừng chương trình.

  • Ngược lại xuất ra "No solution"


\(\color{#008b8b}{\text{Tiếp cận}}\)

  • Vì mảng tăng dần, nên duyệt từ \(l = 1 \rightarrow n\) thì giá trị \(a_l\) sẽ tăng dần nên \(a_r\) nhỏ dần để thỏa mãn \(a_l + a_r \leq x\) với \(r\) lớn nhất

  • Vậy áp dụng kĩ thuật hai con trỏ, cho con trỏ \(l = 1 \rightarrow n\) và con trỏ \(r = n \rightarrow 1\). Nếu \(a_l + a_r \leq x\) rồi thì dừng, ngược lại tiếp túc giảm \(r\)


\(\color{#008b8b}{\text{Độ phức tạp}}\)

  • Nhận dữ liệu mất \(O(n)\)

  • Tìm kết quả mất \(O(l) + O(r) = O(n) + O(n)\)

  • Xuất kết quả mất \(O(1)\)


\(\color{#008b8b}{\text{Code tham khảo }}\): Hai con trỏ

\(^{^{\color{purple}{\text{Độ phức tạp : }} O(n)\ \color{purple}{\text{thời gian}}\ ||\ O(n)\ \color{purple}{\text{bộ nhớ}}}}\)

C++
#include <iostream>

using namespace std;

const int LIM = 1e6 + 16;

int a[LIM];
int main()
{
    int n, x;
    cin >> n >> x;

    for (int i = 1; i <= n; ++i)
        cin >> a[i];

    for (int l = 1, r = n; l < r; ++l)
    {
        while (l < r - 1 && a[l] + a[r] > x) --r;
        if (a[l] + a[r] == x)
        {
            cout << l << ' ' << r;
            return 0;
        }
    }

    cout << "No solution";
    return 0;
}


Comments

There are no comments at the moment.