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