對稱二叉樹題解
阿新 • • 發佈:2018-12-27
對稱二叉樹出處
這道題。。。。。。 本蒟蒻用暴力+輸入輸出優化+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左右