1. 程式人生 > 其它 >【題解】P5018 [NOIP2018 普及組] 對稱二叉樹

【題解】P5018 [NOIP2018 普及組] 對稱二叉樹

在 szkzyc 的幫助下 A 了!!!!!


主要思路:

列舉以 $1~n$ 個結點為根結點的子樹,判斷這個子樹是不是對稱的,如果是,就計算這個子樹的結點數量。通過打擂臺的方式,算出最大對稱二叉子樹的節點數。


需要定義的變數和函式:

1. ans : 判斷這個子樹是否為對稱的變數。

2. check( ) 函式:判斷這個子樹是否對稱的函式。

3. get_node( ) 函式:計算這個子樹的節點數量。


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

struct node1{
    int leftson;//下標
    int rightson;//下標
    int v;//權值
}A[1000009];

int n;
int ans;
int maxnum = 1;
int nodesum = 0;

void init() for(int i=0; i<1000009; i++) A[i].leftson = A[i].rightson = A[i].v = -1;    

//left,right 為下標
void check(int left, int right){
    if(left == -1 && right == -1) return ;//如果左右都為空就返回
    if(A[left].v != A[right].v || (left == -1 || right == -1)){//判斷是否為對稱二叉樹 
        ans = -1;
        return ;
    } 
    check(A[left].leftson,A[right].rightson);
    check(A[left].rightson,A[right].leftson);
}

void get_node(int k){
    if(k == -1)return;
    nodesum++;
    int l1,r1;
    l1 = A[k].leftson;
    r1 = A[k].rightson;
    get_node(l1);
    get_node(r1);
    return;
}
/*
int get_node(int id){
    if(id == -1) return 0;
    return get_node(A[id].leftson) + get_node(A[id].rightson) + 1;
}*/

int main(){
    scanf("%d",&n);
    init();
    for(int i=1; i<=n; i++) scanf("%d",&A[i].v);
    for(int i=1; i<=n; i++) scanf("%d %d",&A[i].leftson,&A[i].rightson);
    for(int i=1; i<=n; i++){//列舉以第i個結點為根的子樹
        ans = 1;
        check(A[i].leftson,A[i].rightson);
        if(ans == 1){
            nodesum = 0;
            get_node(i);
            maxnum = max(maxnum, nodesum);
        }
    }
    printf("%d",maxnum);
    return 0;
}

註釋的 get_node 也是正確的。


一些感言:

1. 思路要清晰,第一遍沒有調出來主要因為思路太混亂。

2. 程式碼能力還要提高,主要是遞迴這方面。