题目链接:https://oj.ismdeep.com/contest/problem?id=1396&pid=7
H: CBT?
时间限制: 1 s 内存限制: 128 MB
题目描述
对于二叉树,如果这棵树的节点排布是按行从上到下,每行从左到右挨个放置,中间不会有空闲的节点。则我们称之为完全二叉树。
注:这棵树的根节点的值一定是1
输入
输入数字正整数n (1≤n≤201≤n≤20)
接下来n行,每行为两个数字(a,b)和一个字符c(L 或者 R),如果字符c是L,则表示b是a的左子节点;如果字符c是R,则表示b是a的右子节点。 (1≤a,b≤30001≤a,b≤3000)
输出
判断这棵树是否为完全二叉树,如果是则输出Yes,否则输出No
样例输入
5
1 2 L
1 3 R
2 4 L
2 5 R
3 6 L
样例输出
Yes
提示
样例解释:样例所描述的二叉树结构如下
很显然这是一个完全二叉树。
这题wa了很多发,最后总算是改出来了,具体思路代码:
#include<iostream> #include<math.h> #include<string.h> #include<stdio.h> #include<queue> using namespace std; const int maxn=3000+5; struct p { int l=0,r=0; }; queue<p>q; int a[maxn][2];//a[i][0]代表i的左儿子的值 a[i][1]代表i的右儿子的值 void solve() { p q1; if(a[1][0]!=0) q1.l=a[1][0]; if(a[1][1]!=0) q1.r=a[1][1]; q.push(q1);//把根节点入队列 while(!q.empty()) { int flag=0; q1=q.front(); q.pop(); if(q1.l==0&&q1.r!=0)//左儿子为空 右儿子却不为空 肯定不是完全二叉树 { cout<<"No"<<endl; return ; } if((q1.l!=0&&q1.r==0)&&(!q.empty()))//左儿子不为空 右儿子为空 但是队列却不为空 { cout<<"No"<<endl; return ; } if(q1.l!=0) { p q2;//把左儿子入队列 int s=q1.l; if(a[s][0]!=0) q2.l=a[s][0]; if(a[s][1]!=0) q2.r=a[s][1]; if(q2.l!=0||q2.r!=0)//注意!!! 就是因为这里wa了好几发 因为我要把一个节点入队 肯定要该节点有值 不然入了个空节点就错了 q.push(q2); else flag=1; } if(q1.r!=0) { p q2; int s=q1.r; if(a[s][0]!=0) q2.l=a[s][0]; if(a[s][1]!=0) q2.r=a[s][1]; if(q2.l!=0||q2.r!=0) { if(flag==1)//左儿子为空 右儿子却不为空 { cout<<"No"<<endl; return ; } q.push(q2); } } } cout<<"Yes"<<endl; } int main() { int n,l,r; char c; memset(a,0,sizeof(a)); cin>>n; for(int i=0;i<n;i++) { cin>>l>>r>>c; if(c=='L') a[l][0]=r; else a[l][1]=r; } solve(); return 0; }