zoukankan      html  css  js  c++  java
  • 【Noip2018pj】【对称二叉树】

    纪念一下这题考场(AC),从而稳住了省一(qaq).其实个人认为这题没有(T3)难,,只要稍微模拟一下就好了。

    正文部分

    首先我们可以画一颗二叉树

    图片来自于互联网。至于点权不用在意。
    然后我们就找到了一种模拟方法:
    对于一个节点,有两种往下递推方法:
    ①:左边节点向左边走,右边节点往右边走
    ②:左边节点往右边走,右边节点往左边走。
    至于为什么是对的?其实自己在这张图上模拟一下就好了。
    有了基本的思想,我们就可以开始构造函数。
    对于check(int,int)函数,表示当前递归到的LR。看一下这部分的代码:

        if(now_l == -1 && now_r == -1) return 1;    
        //没有节点,返回正确
        if(val[now_l] != val[now_r]) return 0;
        //权值不等,返回错误
        if(!in_chk(now_l,now_r)) return 0;   
        //结构不等,返回错误
        int i;
        if(!check(tree[now_l][0] , tree[now_r][1]))
        //递归情况1不满足,返回错误
        return 0;
        if(!check(tree[now_l][1] , tree[now_r][0]))
        //递归情况2不满足,返回错误
        return 0;
        //两种情况都满足,返回正确。
        return 1; 
    

    对于in_chk函数,无非就是特判一下-1的情况,可以自行理解。
    对于memson函数,预处理出所节点的子节点数,注意返回时要+1,因为还要算上自身。
    最后附上考场代码

    // luogu-judger-enable-o2
    #include <bits/stdc++.h>
    #define il inline
    #define gc getchar
    const int MAXN = 1e6 + 10;
    const int INF = 0x7f7f7f7f;
    using namespace std;
    int sons[MAXN],tree[MAXN][2],val[MAXN];
    int n,m,i,j,k,Ans = -INF;
    il int read() {
        int ret = 0;char c;bool sign = 0;
        for(c = gc();!isdigit(c);c = gc()) sign |= c == '-';
        for(;isdigit(c);c = gc()) ret = (ret << 1) + (ret << 3) + (c ^ 48);
        return sign ? -ret : ret;
    }
    int memson(int now) {
        int ret = 0;
        if(tree[now][0] != -1) ret += memson(tree[now][0]);
        if(tree[now][1] != -1) ret += memson(tree[now][1]);
        return sons[now] = ret + 1;
    }
    il bool in_chk(int a,int b) {
        if(tree[a][0] == -1 && tree[b][1] != -1) return 0;
        if(tree[a][1] == -1 && tree[b][0] != -1) return 0;
        if(tree[b][0] == -1 && tree[a][1] != -1) return 0;
        if(tree[b][1] == -1 && tree[a][0] != -1) return 0;
        return 1;
    }
    bool check(int now_l , int now_r) {
        if(now_l == -1 && now_r == -1) return 1;  
        if(val[now_l] != val[now_r]) return 0;
        if(!in_chk(now_l,now_r)) return 0;
        int i;
        if(!check(tree[now_l][0] , tree[now_r][1])) return 0;
        if(!check(tree[now_l][1] , tree[now_r][0])) return 0;
        return 1; 
    }
    int main() {
        n = read();
        for(i = 1;i <= n;i++) val[i] = read();
        for(i = 1;i <= n;i++) tree[i][0] = read(),tree[i][1] = read();
        memson(1);	
        for(i = 1;i <= n;i++) {
            if(tree[i][0] == -1 && tree[i][1] == -1) Ans = max(Ans,1);
            else {
                if(val[tree[i][0]] != val[tree[i][1]]) continue;
                if(tree[i][0] == -1 && tree[i][1] != -1) continue;
                if(tree[i][1] == -1 && tree[i][0] != -1) continue;
                if(check(tree[i][0],tree[i][1])) Ans = max(Ans,sons[i]);	
            } 
        }
        printf("%lld",1LL * Ans);
        return 0;
    }
    
  • 相关阅读:
    图解JavaScript原型和原型链
    hash数组快速查找一个字符串中出现最多的字符,并统计出现的次数
    JS中数组和字符串的方法大全
    用js实现排列组合
    js中一个对象当做参数传递时候?
    用JavaScript按一定格式解析出URL 串中所有的参数
    从Object.definedProperty中看vue的双向数据的绑定
    Uncaught (in promise) TypeError:的错误
    vue之生命周期的一点总结
    原子性和原子性操作
  • 原文地址:https://www.cnblogs.com/Sai0511/p/10360598.html
Copyright © 2011-2022 走看看