Hướng giải của Tiền Tố Chung Dài Nhất


Nhớ rằng hướng dẫn giải này chỉ nên sử dụng khi bế tắc, và tuyệt đối không nên sao chép mã nguồn kèm theo. Hãy tôn trọng tác giả bài tập và người viết hướng dẫn giải.
Nộp mã nguồn lời giải chính thức trước khi giải bài tập đó có thể khiến bạn bị ban.

Tác giả: kienadmin

Hướng dẫn giải

Bài toán tìm độ dài tiền tố chung dài nhất của từ truy vấn \(S\) với bất kỳ từ nào trong từ điển. Ta chèn toàn bộ từ điển \(N\) từ vào cấu trúc Trie thông thường. Với mỗi truy vấn từ \(S\), ta duyệt dọc theo cây Trie từ gốc theo các ký tự của \(S\):

  • Cứ mỗi lần di chuyển thành công sang node con, ta tăng độ dài tiền tố chung dài nhất thêm 1.
  • Nếu gặp đường đi cụt (node con tương ứng bằng nullptr), ta dừng lại và trả về kết quả độ dài hiện tại.

Độ phức tạp thời gian:

  • Khởi tạo: \(O(\text{tổng độ dài từ điển})\)
  • Mỗi truy vấn: \(O(|S|)\)

Mã nguồn C++ mẫu

#include <bits/stdc++.h>
using namespace std;

struct TrieNode {
    TrieNode* children[26];
    TrieNode() {
        for (int i = 0; i < 26; i++) children[i] = nullptr;
    }
};

struct Trie {
    TrieNode* root;
    Trie() { root = new TrieNode(); }

    void insert(const string& s) {
        TrieNode* cur = root;
        for (char c : s) {
            int idx = c - 'a';
            if (cur->children[idx] == nullptr) {
                cur->children[idx] = new TrieNode();
            }
            cur = cur->children[idx];
        }
    }

    int getLongestPrefix(const string& s) {
        TrieNode* cur = root;
        int len = 0;
        for (char c : s) {
            int idx = c - 'a';
            if (cur->children[idx] == nullptr) break;
            cur = cur->children[idx];
            len++;
        }
        return len;
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n, q;
    if (!(cin >> n >> q)) return 0;

    Trie trie;
    for (int i = 0; i < n; i++) {
        string s;
        cin >> s;
        trie.insert(s);
    }

    for (int i = 0; i < q; i++) {
        string s;
        cin >> s;
        cout << trie.getLongestPrefix(s) << "\n";
    }
    return 0;
}

Nhận xét

Không có ý kiến tại thời điểm này.