对称二叉树题解

对称二叉树出处

这道题。。。。。。 本蒟蒻用暴力+输入输出优化+inline卡时间勉强AC 我的思路很简单,从根开始依次往下遍历,找最大值 注意题目描述:::

本题中约定,以节点 TT 为子树根的一棵“子 树”指的是:节点TT 和它的全部后代节点构成的二叉树

本题中约定,以节点 TT 为子树根的一棵“子 树”指的是:节点TT 和它的全部后代节点构成的二叉树

本题中约定,以节点 TT 为子树根的一棵“子 树”指的是:节点TT 和它的全部后代节点构成的二叉树

所以只需要check一遍判断就好了 我的代码很复杂 首先来看输入输出优化 输入优化:

inline void sc(int &x) {//读入要改变x的值
    x=0;int f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}//判断正负
    while(s>='0'&&s<='9'){x=x*10+s-48;s=getchar();}//读入
    x*=f;//稍微学过一点的都应该看得懂。。。
}

输出优化:

inline void pr(int x) {
    if(x<0)putchar('-'),x=-x;//负数
    if(x>9)pr(x/10);//用递归从前往后输出
    putchar(x%10+48);//输出
}

以上两段代码都是利用c++输入输出字符比数字快的原理 然后来看主程序:

int main() {
    sc(n);
    for(int i=1;i<=n;i++)
        sc(a[i].v);
    for(int i=1;i<=n;i++)
        sc(a[i].l),sc(a[i].r);
    dfs(1);
    pr(ans);
}

再来看dfs:

inline void dfs(int x) {//从根节点开始搜
    tot=3;
    if(a[x].l==-1&&a[x].r==-1)//左右儿子都是-1
        ans=max(ans,1),tot=3;//判断,tot=3在代码后面解释
    else if(a[x].l!=-1&&a[x].r!=-1)//左右儿子都不是-1
        if(check(a[x].l,a[x].r))//判断是不是一棵对称二叉树
            ans=max(ans,tot),tot=3;
    if(a[a[x].l].v!=a[a[x].r].v||a[x].l==-1||a[x].r==-1||!check(a[x].l,a[x].r)) {//在权值不等或一边没有或不是对称二叉树的情况下,要两边分别搜
        if(a[x].l!=-1)//左边有值搜左边
            dfs(a[x].l);
        tot=3;
        if(a[x].r!=-1)//右边有值搜右边
            dfs(a[x].r);
    }
    tot=3;
}
/*
此处的inline可以减少函数调用的时间
*/

tot=3是因为如果能进check的话就至少有三个。 其中根为一个,左右儿子有两个 因为在check里面没打,所以就这样了 接下来是check:

inline bool check(int x,int y) {//我判断得很复杂,大家可以想想怎么改进
    if(x==-1&&y==-1) return 1;
    else if(a[x].v!=a[y].v){tot=0;return 0;}
    else if((a[x].l==-1&&a[y].r!=-1)||(a[x].l!=-1&&a[y].r==-1)||(a[x].r==-1&&a[y].l!=-1)||(a[x].r!=-1&&a[y].l==-1)){tot=3;return 0;}
    else if(a[x].l!=-1&&a[y].r!=-1&&a[x].r!=-1&&a[y].l!=-1&&check(a[x].l,a[y].r)&&check(a[x].r,a[y].l)){tot+=4;return 1;}
    else if(a[x].l==-1&&a[y].r==-1&&a[x].r!=-1&&a[y].l!=-1&&check(a[x].r,a[y].l)){tot+=2;return 1;}
    else if(a[x].r==-1&&a[y].l==-1&&a[x].l!=-1&&a[y].r!=-1&&check(a[x].l,a[y].r)){tot+=2;return 1;}
    else if(a[x].l==-1&&a[x].r==-1&&a[y].l==-1&&a[y].r==-1)return 1;
    return check(a[x].l,a[y].r)&&check(a[x].r,a[y].l);
}
/*
第一个if是判断如果没有儿子就return
第一个else if是判断两边权值不相等就不成立
第二个else if是判断儿子对不对称,不对称就不成立
第三个else if是判断两个点都有儿子且儿子对称,要加4个点
第四个else if是判断x的左儿子和y的右儿子对不对称,要加2个点
第五个else if是判断x的右儿子和y的左儿子对不对称,要加2个点
最后一个else if是判断如果两个点都没有儿子,树也是成立的
最后就是判断
*/

是不是超复杂。。。。。。 下面是完整代码

#include<cstdio>
inline void sc(int &x) {
    x=0;int f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-48;s=getchar();}
    x*=f;
}
inline void pr(int x) {
    if(x<0)putchar('-'),x=-x;
    if(x>9)pr(x/10);
    putchar(x%10+48);
}
inline int max(int x,int y) {
    return x>y?x:y;
}
struct node {
    int l,r,v;
}a[1000005];
int n,k,ans=1,tot=3;
inline bool check(int x,int y) {
    if(x==-1&&y==-1) return 1;
    else if(a[x].v!=a[y].v){tot=0;return 0;}
    else if((a[x].l==-1&&a[y].r!=-1)||(a[x].l!=-1&&a[y].r==-1)||(a[x].r==-1&&a[y].l!=-1)||(a[x].r!=-1&&a[y].l==-1)){tot=3;return 0;}
    else if(a[x].l!=-1&&a[y].r!=-1&&a[x].r!=-1&&a[y].l!=-1&&check(a[x].l,a[y].r)&&check(a[x].r,a[y].l)){tot+=4;return 1;}
    else if(a[x].l==-1&&a[y].r==-1&&a[x].r!=-1&&a[y].l!=-1&&check(a[x].r,a[y].l)){tot+=2;return 1;}
    else if(a[x].r==-1&&a[y].l==-1&&a[x].l!=-1&&a[y].r!=-1&&check(a[x].l,a[y].r)){tot+=2;return 1;}
    else if(a[x].l==-1&&a[x].r==-1&&a[y].l==-1&&a[y].r==-1)return 1;
    return check(a[x].l,a[y].r)&&check(a[x].r,a[y].l);
}
inline void dfs(int x) {
    tot=3;
    if(a[x].l==-1&&a[x].r==-1)
        ans=max(ans,1),tot=3;
    else if(a[x].l!=-1&&a[x].r!=-1)
        if(check(a[x].l,a[x].r))
            ans=max(ans,tot),tot=3;
    if(a[a[x].l].v!=a[a[x].r].v||a[x].l==-1||a[x].r==-1||!check(a[x].l,a[x].r)) {
        if(a[x].l!=-1)
            dfs(a[x].l);
        tot=3;
        if(a[x].r!=-1)
            dfs(a[x].r);
    }
    tot=3;
}
int main() {
    sc(n);
    for(int i=1;i<=n;i++)
        sc(a[i].v);
    for(int i=1;i<=n;i++)
        sc(a[i].l),sc(a[i].r);
    dfs(1);
    pr(ans);
}

大概用时670ms左右

猜你喜欢

转载自blog.csdn.net/qq_43890190/article/details/84758711