1. 程式人生 > >【Noip2018pj】【對稱二叉樹】

【Noip2018pj】【對稱二叉樹】

cpp 什麽是 pri amp using ger 節點 結構 分享圖片

紀念一下這題考場\(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;
}

【Noip2018pj】【對稱二叉樹】