【题解】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.  代码能力还要提高,主要是递归这方面。

上一篇:仿B站项目(3)页面配置


下一篇:P5020 [NOIP2018 提高组] 货币系统