Hướng dẫn cho Giờ đối xứng


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{goldenrod}{\text{Approach <Brute-forces>}}\)

  • Gọi \(h\) là số giờ, \(m\) là số phút

  • Trong khi \(h\)\(m\) chưa đối xứng ta sẽ thử tăng \(m\) rồi tăng \(h\) lên

Khi \(m = 60\) thì gán \(m = 0\)\(h = h + 1\)

Khi \(h = 24\) thì gán \(h = 0\)

  • Để kiểm tra đối xứng ta chỉ cần kiểm tra xem hai số có là nghịch đảo của nhau không

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

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

C++
int inv(int x) { return (x % 10) * 10 + x / 10; } /// số nghịch đảo
int main() {
    int h = readInt();
    int m = readInt();
    do
    {
        if (++m == 60)
        {
            m = 0;
            if (++h == 24) h = 0;
        }
    } 
    while (h != inv(m));
    cout << h / 10 << h % 10 << ':' << m / 10 << m % 10;
    return 0;
}

\(\color{goldenrod}{\text{Approach <Branch-and-bound>}}\)

  • Chúng ta có thể lưu trực tiếp toàn bộ xâu thỏa mãn và kiểm tra nếu hợp lệ thì in ra luôn

  • Vì số cách chọn thỏa mãn rất ít so với tổng số cách phải trâu nên mình đã loại bỏ các trường hợp không cần xét đến

  • Với \(res[]\) là mảng kết quả tăng dần

Nếu time nằm trong khoảng \(res[i - 1]..res[i] - 1\) thì kết quả sẽ là \(res[i]\) là thời gian sau đó

Lưu ý trường hợp \(time >= "23:32"\) thì in ra \("00:00"\) nhé


\(\color{green}{\text{Preference AC Code }}\): Branch-and-bound

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

C++
int main()
{
    vector<string> res = {
        "00:00", "01:10", "02:20", "03:30", "04:40", "05:50", "10:01", "11:11",
        "12:21", "13:31", "14:41", "15:51", "20:02", "21:12", "22:22", "23:32"
    };

    string time;
    cin >> time;

    if (time >= res.back())
    {
        cout << res.front();
        return 0;
    }

    int n = int(res.size());
    for (int i = n - 1; i >= 1; --i)
    {
        if (res[i] > time && time >= res[i - 1])
        {
            cout << res[i];
            return 0;
        }
    }
    return 0;
}

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

  • Chúng ta cũng có thể sài hash để so sánh bằng số sẽ nhanh hơn

\(\color{green}{\text{Preference AC Code }}\): Hash

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

C++
int main()
{
    vector<int> hash = {
           0,  110,  220,  330,  440,  550, 1001, 1111, 
        1221, 1331, 1441, 1551, 2002, 2112, 2222, 2332
    };

    vector<string> res = {
        "00:00", "01:10", "02:20", "03:30", "04:40", "05:50", "10:01", "11:11",
        "12:21", "13:31", "14:41", "15:51", "20:02", "21:12", "22:22", "23:32"
    };

    int h = readInt();
    int m = readInt();
    int time = h * 100 + m;

    if (time >= hash.back())
    {
        cout << res.front();
        return 0;
    }

    int n = int(hash.size());
    for (int i = n - 1; i >= 1; --i)
    {
        if (hash[i] > time && time >= hash[i - 1])
        {
            cout << res[i];
            return 0;
        }
    }
    return 0;
}


Bình luận


  • 0
    lagiahuy    5:35 p.m. 1 Tháng 11, 2021

    mình bị 70%, nhờ bạn kiểm tra lại hộ mình cái!