【Noip2018pj】【對稱二叉樹】
阿新 • • 發佈:2019-02-11
cpp 什麽是 pri amp using ger 節點 結構 分享圖片
紀念一下這題考場\(AC\),從而穩住了省一\(qaq\).其實個人認為這題沒有\(T3\)難,,只要稍微模擬一下就好了。
正文部分
首先我們可以畫一顆二叉樹
圖片來自於互聯網。至於點權不用在意。
然後我們就找到了一種模擬方法:
對於一個節點,有兩種往下遞推方法:
①:左邊節點向左邊走,右邊節點往右邊走
②:左邊節點往右邊走,右邊節點往左邊走。
至於為什麽是對的?其實自己在這張圖上模擬一下就好了。
有了基本的思想,我們就可以開始構造函數。
對於check(int,int)
函數,表示當前遞歸到的L
和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])) //遞歸情況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】【對稱二叉樹】