一、题目概述
若给定树为完全二叉树输出"YES"和最后一个结点下标,否则输出"NO"和根节点下标
二、思路
1、根节点的确定
根节点一定不为任一结点的子树,则输入时记录每个结点是否为子树的状态。
2、完全二叉树的判定
若一个树非完全二叉树,则一定存在某一层,该层两个结点间存在空结点。对树层序遍历时该现象可以在队列中得到反映,即:结点的孩子无论是否为空均入队,若出队结点是空结点,且后续出队有非空结点,则不是完全二叉树。
注意:测试点内存超限,考虑是否用了单字符读取输入,当输入下标为两位数时不能正确读入。
三、代码
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <queue>
using namespace std;
int main()
{
int N, tag = 0, flag = 1, last, root, v;
scanf("%d", &N);
vector<int> lchild(N), rchild(N), isroot(N, 1);
for(int i = 0; i < N; ++i)
{
char c1[3], c2[3];
scanf("%s %s", c1, c2);
lchild[i] = c1[0] == '-' ? -1:atoi(c1);
rchild[i] = c2[0] == '-' ? -1:atoi(c2);
if(c1[0] != '-')
isroot[atoi(c1)] = 0;
if(c2[0] != '-')
isroot[atoi(c2)] = 0;
}
for(root = 0; !isroot[root]; ++root);
queue<int> q;
q.push(root);
while(!q.empty())
{
v = q.front();
q.pop();
if(v != -1)
{
last = v;
if(tag)
flag = 0;
q.push(lchild[v]);
q.push(rchild[v]);
}
else tag = 1;
}
printf("%s %d", flag ? "YES":"NO", flag ? last:root);
}