Hướng dẫn cho Số lẻ loi 1


Chỉ sử dụng khi thực sự cần thiết như một cách tôn trọng tác giả và người viết hướng dẫn này.

Chép code từ bài hướng dẫn để nộp bài là hành vi có thể dẫn đến khóa tài khoản.

Authors: SPyofgame


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

\(\color{red}{\text{Khuyến khích bạn đọc trước khi đọc phần lời giải xin hãy thử code ra thuật của mình dù nó có sai hay đúng}}\)

\(\color{red}{\text{Sau đó từ phần bài giải và thuật toán trước đó mà đối chiếu, rút nhận xét với thuật của mình và thu được bài học (không lãng phí thời gian đâu).}}\)



\(\color{orange}{\text{Hint 1 <Brute-forces>}}\)

  • Với mỗi truy vấn, ta tính số đảo ngược \(Rev(A)\) và kiểm tra từng chữ số của \(a + Rev(A)\) có hợp lệ hay không

\(\color{goldenrod}{\text{Approach <Brute-forces>}}\)

  • Cách tính \(Rev(A)\)

Gọi \(tam = A, rev = 0\), ta sẽ lần lượt đảo ngược các chữ số của \(tam\) sang \(rev\)

Để làm vậy, cách đơn giản nhất là lấy chữ số phải cùng của \(tam\) chèn sàng bên phải \(rev\) tới khi \(tam\) không còn chữ số nào

Để lấy chữ số bên phải cùng \(tam\) ta dùng phép \(tam\ \text{mod}\ 10\)

Để xóa chữ số bên phải cùng \(tam\) ta dùng phép \(tam = \lfloor \frac{tam}{10} \rfloor\)

Để kiểm tra xem \(tam\) còn chữ số nào nữa không ta dùng phép \(if\ (tam = 0)\)

Để chèn phải chữ số \(d\) sang \(rev\) ta dùng phép \(rev = 10 \times rev + d\)

  • Cách kiểm tra

Nếu số \(n\) chia hết cho 10 thì số đầu tiên chèn sang \(rev\)\(0\) nên ta sẽ loại trường hợp này

Duyệt từng chữ số và kiểm tra nếu có phần tử chẵn thì loại


\(\color{green}{\text{Preference AC Code }}\): Brute-forces

\(^{^{\color{purple}{\text{Complexity : }} O(log_{10}(n))\ \color{purple}{\text{time}}\ ||\ O(1)\ \color{purple}{\text{memory}}}}\)

C++
bool check(ll n) {
    ll rev = 0;
    for (ll t = n; t; rev = 10 * rev + t % 10, t /= 10);
    if (n % 10 == 0) return false;

    ll sum = n + rev;
    do if (sum % 2 == 0) return false;
    while (sum /= 10);

    return true;
}

\(\color{orange}{\text{Hint 2 <String>}}\)

  • Chúng ta cũng có thể nhận kiểu string và tính tổng từng cặp đối xứng của nó

Lưu ý trong trường hợp tổng 2 chữ số là số gồm 2 chữ số ta phải lưu biến nhớ


\(\color{goldenrod}{\text{Approach <String>}}\)

  • Khi nhận vào xâu, nếu xâu có chữ số cuối cùng là 0 thì loại ngay

  • Duyệt qua từng chữ số

Vừa tính tổng \(sumdig\) hiện tại bằng tổng đối xứng \((a + reva)\) cộng biến nhớ trước đó

Biến nhớ \(rem = 1\) khi \(sumdig >= 10\)\(rem = 0\) khi \(sumdig < 10\)

Nếu \(sumdig\) chẵn thì loại ngay


\(\color{green}{\text{Preference AC Code }}\): String, Brute-forces

\(^{^{\color{purple}{\text{Complexity : }} O(log_{10}(n))\ \color{purple}{\text{time}}\ ||\ O(1)\ \color{purple}{\text{memory}}}}\)

C++
bool check(const string &s)
{
    if (s.back() == '0') return false;
    int len = s.size();

    int rem = 0;
    for (int i = 0; i < len; ++i)
    {
        int a    = (s[i] - '0');
        int reva = (s[len - i - 1] - '0');
        int sumdig = a + reva + rem;
        rem = (sumdig >= 10);

        if (sumdig % 2 == 0) return false;
    }

    return true;
}


Bình luận

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