POJ 1105 S-Trees(二分)

POJ 1105 S-Trees

題意: 定義一種結構叫做S-tree,給定深度n,S-tree是一顆深度爲n(n<=7)的滿二叉樹(根節點深度爲0),樹節點上標記着變量的名字,並且樹的同一層上的變量名相同,葉子節點爲1,或者0。例如給定深度爲3的兩顆樹
在這裏插入圖片描述
所以表達一棵樹只需要給出變量序列和葉子節點即可,左邊的樹可以表達爲

x1 x2 x3 00000111

右邊的樹表達爲:

x3 x1 x2 00010011

x1, x2, x3通過VVA(Variable Values Assignment)賦值, 例如VVA=110對於第一個圖表示x1 = 1, x2 =1, x3 = 1,對於第二個圖表示x3 = 1, x1 = 1, x2 = 0。

給定S-tree和VVA,定義一種遍歷樹的方法,對於樹中的節點變量,如果變量爲0,則走左子樹,變量爲1則走右子樹,那麼對於VVA=110,左邊的樹遍歷到從左往右倒數第二個葉子節點。

題目給定多個S-tree,和VVA,問遍歷結果

思路: 可以按照樹的遍歷去做,這樣思路直接。但是可以看到最後遍歷樹只需要知道走到哪一個葉子節點即可。

二分思路來源在於:走左子樹,則最終結果一定不在葉子節點的右半側,走右子樹,最終結果一定不在葉子節點的左半側,如此設定start,end指定搜索下標的範圍,不斷縮小範圍,同時需要配上手工先行驗證想法。

深度爲n的樹,葉子節點有2n2^n個,用數組char terminal_node[150]存儲,只需要找到遍歷最後的下標index即可。設葉子節點數組下標從1開始存放數字,且start=1,end=2n2^n,mid=(start+end)/2。對於給定的VVA,遍歷前n-1個VVA的值,如果某個變量爲0,走左子樹,那麼最終的值不可能在mid右邊,那麼修改end=mid,mid=(start+end)/2,如果變量爲1同理,不可能在mid左邊,修改start=mid,mid=(start+end)/2,按照這個步驟最終遍歷完n-1個VVA,如果第n個VVA的值爲0,則index = mid即爲最終結果在葉子節點的下標,如果VVA=1,則index = mid+1,最後結果爲terminal_node[index]

代碼

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
//Accepted

int pow(int x, int y) {
    int result = 1;
    for (int i = 0; i < y; i++)
        result *= x;
    return result;
}

int s_tree_function(char vva[], int n) {
    int start = 1, end = (int)pow(2, n);
    int mid = (start + end) / 2;
    for (int i = 0; i < n - 1; i++) {
        if (vva[i] == '0') {
            end = mid;
            mid = (start + mid) / 2;
        }
        else {
            start = end;
            mid = (end + mid) / 2;
        }
    }
    if (vva[n - 1] == '1') mid++;
    return mid;
}

int main() {
    int N;
    int cases = 0;
    while (cin >> N && N != 0) {
        cases++;
        string tmp;
        for (int i = 0; i < N; i++) {
            cin >> tmp;
        }
        char terminal_node[150];
        cin.ignore(1);
        for (int i = 1; i <= (int)pow(2, N); i++) {
            terminal_node[i] = getchar();
        }

        int M; cin >> M;
        printf("S-Tree #%d:\n", cases);
        for (int i = 0; i < M; i++) {
            cin.ignore(1);
            char vva[10];
            for (int i = 0; i < N; i++) {
                vva[i] = getchar();
            }
            int index = s_tree_function(vva, N);
            cout << terminal_node[index];
        }
        cout << endl << endl;

    }

    return 0;
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章