Tìm đường nhảy của chú ếch xanh

Chú Ếch xanh
 Bài toán

Có n chiếc cọc gỗ được xếp thẳng hàng. Chú ếch xanh muốn nhảy qua các chiếc cọc này để tìm tới cọc chú ếch vàng đang đứng. Đương nhiên sẽ có chướng ngại vật trên đường tìm bạn. Mỗi bước nhảy chú ếch xanh có thể nhảy qua k chiếc cọc từ vị trí đứng hiện tại (có thể nhảy sang trái hoặc sang phải).

Ví dụ, nếu k = 1 thì chú ếch có thể nhảy qua duy nhất một chiếc cọc bên cạnh, còn nếu k = 2 thì chú ếch có thể nhảy mà bỏ qua cọc kế bên.

Nhiệm vụ của bạn là hãy xác định xem, sau một chuỗi các bước nhảy thì chú ếch xanh có tìm được chú ếch vàng bạn mình hay không. 

sốnguyên n (0 < n <10^6)

Thuật toán

Bài toán “Tìm đường nhảy của chú ếch xanh” yêu cầu ta phải tìm đường nhảy từ vị trí ban đầu của chú ếch xanh để tới được vị trí của chú ếch vàng. Trên đường đi, có một số chướng ngại vật (các cọc gỗ) và chú ếch xanh có thể nhảy qua k chiếc cọc liên tiếp.

Thuật toán giải bài toán trên có thể được thực hiện như sau:

  1. Đầu tiên, ta xác định vị trí của chú ếch vàng trong mảng các cọc gỗ.

  2. Sau đó, ta sử dụng một mảng đánh dấu f để lưu trữ thông tin về các vị trí có thể đến được từ vị trí hiện tại của chú ếch xanh.

  3. Ta duyệt qua mỗi vị trí i trong mảng các cọc gỗ. Nếu vị trí đó chứa cọc gỗ, ta tìm các vị trí có thể đến được từ vị trí hiện tại và lưu trữ thông tin này vào mảng f.

  4. Nếu vị trí i không chứa cọc gỗ, ta tìm các vị trí có thể đến được từ vị trí hiện tại. Nếu không có vị trí nào có thể đến được, ta gán f[i] = false. Ngược lại, ta duyệt qua các vị trí đó và kiểm tra xem nếu có ít nhất một vị trí mà f[j] = true thì ta gán f[i] = true.

  5. Sau khi duyệt qua tất cả các vị trí, nếu f[1] = true thì chú ếch xanh có thể tới được vị trí của chú ếch vàng, ngược lại thì không thể.

Thuật toán này có độ phức tạp O(nk), với n là số lượng cọc gỗ và k là số lượng cọc gỗ mà chú ếch xanh có thể nhảy qua.

Cài đặt bài toán với Python

def find_path(n, k, a):
    # Tìm vị trí của chú ếch vàng
    gold_position = a.index('G')

    # Tạo mảng đánh dấu f và gán f[gold_position] = true
    f = [False] * n
    f[gold_position] = True

    # Duyệt qua từng vị trí trong mảng a
    for i in range(n):
        if a[i] == 'X':
            continue

        # Tìm các vị trí có thể đến được từ vị trí hiện tại
        possible_positions = []
        for j in range(1, k+1):
            if i-j >= 0 and f[i-j]:
                possible_positions.append(i-j)
            if i+j < n and f[i+j]:
                possible_positions.append(i+j)

        # Nếu có ít nhất một vị trí có thể đến được, gán f[i] = true
        if len(possible_positions) > 0:
            f[i] = True

    # Trả về kết quả
    if f[0]:
        return 'YES'
    else:
        return 'NO'

Cài đặt bài toán với C++

#include <iostream>
#include <vector>

using namespace std;

string find_path(int n, int k, vector<char> a) {
    // Tìm vị trí của chú ếch vàng
    int gold_position;
    for (int i = 0; i < n; i++) {
        if (a[i] == 'G') {
            gold_position = i;
            break;
        }
    }

    // Tạo mảng đánh dấu f và gán f[gold_position] = true
    vector<bool> f(n, false);
    f[gold_position] = true;

    // Duyệt qua từng vị trí trong mảng a
    for (int i = 0; i < n; i++) {
        if (a[i] == 'X') {
            continue;
        }

        // Tìm các vị trí có thể đến được từ vị trí hiện tại
        vector<int> possible_positions;
        for (int j = 1; j <= k; j++) {
            if (i-j >= 0 && f[i-j]) {
                possible_positions.push_back(i-j);
            }
            if (i+j < n && f[i+j]) {
                possible_positions.push_back(i+j);
            }
        }

        // Nếu có ít nhất một vị trí có thể đến được, gán f[i] = true
        if (!possible_positions.empty()) {
            f[i] = true;
        }
    }

    // Trả về kết quả
    if (f[0]) {
        return "YES";
    }
    else {
        return "NO";
    }
}

int main() {
    int n, k;
    cin >> n >> k;

    vector<char> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }

    cout << find_path(n, k, a) << endl;

    return 0;
}

Thuật toán được sử dụng trong cách cài đặt trên là thuật toán duyệt mảng tuyến tính. Cụ thể, chúng ta duyệt mảng các cọc gỗ từ trái sang phải, và tại mỗi vị trí, ta kiểm tra xem chú ếch xanh có thể nhảy tới vị trí đó từ vị trí trước đó hay không. Nếu có, ta tiếp tục duyệt về phía trước, nếu không ta tiếp tục duyệt từ vị trí hiện tại với k chiếc cọc tiếp theo. Nếu không tìm thấy vị trí của chú ếch vàng trong mảng cọc gỗ, ta kết luận rằng chú ếch xanh không thể tìm thấy chú ếch vàng.

Vì vậy, cách cài đặt này có độ phức tạp thấp và phù hợp với bài toán này.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *