题目链接:https://www.patest.cn/contests/gplt/L3-010
相信很多人跟小编一样,比赛的时候就算这是一道中文题也不知道这是什么意思,因为对二叉搜索树的概念知道的比较少,对着中文题就跟对着英文题一个感受 _(:з」∠)_,下来一直到题意了,就发现,这道题其实超级简单。
题意是这样的,二叉搜索树,建立的时候秉持着一种大的在左边,小的在右边的原则,每一次插入都放到适合的位置,比如现在的状态是:
现在我们要插入7的话,从根节点开始,7>3,在左子树,7>5,又在左子树,7>6,又在左子树,所以7的位置就是这样:
接下来就是判断是否是完全二叉搜索树,在上面建树的时候小编我采取的是对编号进行离散化,左子树的编号是根节点的2倍,右子树的编号是结点的2倍+1,如果是完全二叉树,那么一定是编号都是从1~n,那么这样的话只要我们最后遍历一次,在1~n之间没有出现没有的情况,就好了。
#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 30;
int a[maxn],tree[maxn];
map<int, int> Map;
int main()
{
int n,num=1,r=1;
scanf("%d", &n);
scanf("%d", &a[0]);
Map[r] = num++;
tree[Map[r]] = a[0];
for(int i=1; i<n; i++)
{
scanf("%d", &a[i]);
r = 1;
while(Map[r])
{
if(a[i] > tree[Map[r]]) r = r<<1;
else r = r<<1|1;
}
Map[r] = num++;
tree[Map[r]] = a[i];
}
int ok = 0;
printf("%d", a[0]);
for(int i=2; i<=31; i++)
{
if(Map[i]) printf(" %d", tree[Map[i]]);
else if(i <= n) ok = 1;
}
if(ok) printf("\nNO\n");
else printf("\nYES\n");
}