zoukankan      html  css  js  c++  java
  • 【题解】【NOIP2018PJ】对称二叉树

    在考场上的玄学思路:

    这道题的思路相对来说还是很好想出来的(

    首先,对于每一个节点,只要右儿子节点与左儿子节点的权值不同,就肯定不是对称的,舍去

    然后,每一次向下走一层的时候,左子树跟右子树的路径取反

    什么意思呢?

    就是,你左子树向右走,右子树就向左走;左子树向左走,右子树向右走

    (如果这里不能理解建议动手画图看一下)

    同理,判断时也取反

    分四种情况:

    • 如果左子树的根节点没有左子树而右子树的根节点有右子树,那么结构上肯定不满足对称性,舍去

    • 如果左子树的根节点没有右子树而右子树的根节点有左子树,那么结构上肯定不满足对称性,舍去

    • 如果左子树的根节点有左子树而右子树的根节点没有右子树,那么结构上肯定不满足对称性,舍去

    • 如果左子树的根节点有右子树而右子树的根节点没有左子树,那么结构上肯定不满足对称性,舍去

    那么什么时候满足对称性呢?

    ——当搜索到两个节点,两个节点同为叶子结点且权值相等时

    但只要有其中某一条路径不满足,整颗子树肯定不满足

    那么,按照以上思路打出来的代码是多少分的呢?我怎么知道

    96分

    用了一次下载数据的机会……(in luogu)

    哦,炸了,极限数据卡成一条链了……

    那么,我们还可以加上什么优化呢?

    给大家3分钟的思考时间……


    优化很简单——只要左右子树的节点数目不同,则结构肯定不对称!

    那么这个优化加上去多少分?

    当然AC啦!

    上代码!喂喂喂音乐老师怎么回事BGM呢

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    struct note
    {
        int left;
        int right;
        int val;
    };
    
    int n,ans;
    note a[1000010];
    int d[1000010];
    
    int fast_read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
            {
                f=-1;
            }
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<3)+(x<<1)+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    
    int dfs(int root)
    {
        //printf("%d
    ",root);
        if(a[root].left==-1&&a[root].right==-1)
        {
            return 1;
        }
        int s=1;
        if(a[root].left!=-1)
        {
            s+=dfs(a[root].left);
        }
        if(a[root].right!=-1)
        {
            s+=dfs(a[root].right);
        }
        d[root]=s;
        return s;
    }
    
    bool dfs2(int left,int right)
    {
        if(a[left].val!=a[right].val)
        {
            return 0;
        }
        if(a[left].left==-1)
        {
            if(a[right].right!=-1)
            {
                return 0;
            }
        }
        if(a[left].right!=-1)
        {
            if(a[right].left==-1)
            {
                return 0;
            }
        }
        if(a[left].left!=-1)
        {
            if(a[right].right==-1)
            {
                return 0;
            }
        }
        if(a[left].right==-1)
        {
            if(a[right].left!=-1)
            {
                return 0;
            }
        }
        if(a[left].right==-1&&a[left].left==-1)
        {
            return 1;
        }
        bool f=1;
        if(!dfs2(a[left].left,a[right].right))
        {
            f=0;
        }
        if(!dfs2(a[left].right,a[right].left))
        {
            f=0;
        }
        return f;
    }
    
    void work()
    {
        for(int i=1;i<=n;i++)
        {
            if(a[i].left!=-1&&a[i].right!=-1)
            {
                if(d[i]>ans&&d[a[i].left]==d[a[i].right]&&dfs2(a[i].left,a[i].right))
                {
                    ans=d[i];
                }
            }
            else
            {
                ans=max(ans,1);
            }
            //printf("%d
    ",ans);
        }
    }
    
    int main()
    {
        //freopen("testdata (2).in","r",stdin);
        n=fast_read();
        for(int i=1;i<=n;i++)
        {
            a[i].val=fast_read();
            d[i]=1;
        }
        for(int i=1;i<=n;i++)
        {
            a[i].left=fast_read();
            a[i].right=fast_read();
        }
        int k=dfs(1);
        work();
        /*
        for(int i=1;i<=n;i++)
        {
            printf("%d
    ",d[i]);
        }
        */
        printf("%d
    ",ans);
        return 0;
    }

    各位,暴力出奇迹啊!

  • 相关阅读:
    Event bubbling
    input/change event practice
    Form event
    Event_Object
    DOM_this keyword
    Random color generator exercise
    DOM_events_addEventListener
    Spring值SpEL
    Spring之使用外部属性文件
    Spring之Bean的作用域
  • 原文地址:https://www.cnblogs.com/tt66ea-blog/p/10057803.html
Copyright © 2011-2022 走看看