【題解】ZeroJudge d432: 第四題:通關密語 (pwd)

【題目敘述】https://zerojudge.tw/ShowProblem?problemid=d432
【姊妹題】d861: NOIP2001 3.求先序排列
【解題想法】Divide & Conquer

  • 使用字元的 ASCII code 當 post_idx 陣列的 index,post_idx 紀錄「後序字串」各個字元出現的順序。
  • 從「中序字串」中找出在「post_idx 陣列」中值最大的(就是在後序字串中位置最後面的)字元,該字元即為目前 subtree 的 root(下例中的「A」)。
  • 輸出 root 字元,再利用它把「中序字串」分成 left tree 和 right tree。
  • 重複標準 Divide & Conquer 做法。
#include <iostream>
using namespace std;

// ASCII code
// 0: 48 (decimal), A: 65, a: 97
int post_idx[100], n;
string in, post;

void func(int in_start, int in_end){
    // 在中序字串中找出root,其在「後序字串中的index值」最大
    if (in_start != in_end){
        int mx = -1, root;
        for (int i = in_start; i < in_end; i++){
            if (post_idx[in[i]-'0'] > mx){
                mx = post_idx[in[i]-'0'];
                root = i;
            }
        }
        cout << in[root];
        // left tree
        func(in_start, root);
        // right tree
        func(root+1, in_end);
    }
}

int main() {
    while(cin >> in >> post){
        n = in.length();
        for (int i = 0; i < n; i++){
            // 用「後序字串」字元的ASCII code當post_idx的index
            post_idx[post[i] - '0'] = i;
        }
        func(0, n);
        cout << "\n";
    }
}
分享本文 Share with friends