【題解】P5018 [NOIP2018 普及組] 對稱二叉樹
阿新 • • 發佈:2021-10-13
在 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. 程式碼能力還要提高,主要是遞迴這方面。