pat 团体天梯赛 L2-004. 这是二叉搜索树吗?
L2-004. 这是二叉搜索树吗?
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
- 其左子树中所有结点的键值小于该结点的键值;
- 其右子树中所有结点的键值大于等于该结点的键值;
- 其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数N(<=1000)。随后一行给出N个整数键值,其间以空格分隔。
输出格式:
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出“YES”,然后在下一行输出该树后序遍历的结果。数字间有1个空格,一行的首尾不得有多余空格。若答案是否,则输出“NO”。
输入样例1:
7
8 6 5 7 10 8 11
输出样例1:
YES
5 7 6 8 11 10 8
输入样例2:
7
8 10 11 8 6 7 5
输出样例2:
YES
11 8 10 7 5 6 8
输入样例3:
7
8 6 8 5 10 9 11
输出样例3:
NO 思路:搜索二叉树的重建,告诉你了前序遍历,那么可以进行递归的找出后序遍历。前序遍历的特性可知,每次递归的查找区间[l,r]的根以及其左右子树,节点l处的值一定是根,因为前序遍历总是先确定出根,之后再去搜索其左子树和右子树。
那么左子树和右子树的范围应当如何确定呢?首先左右子树当中所有的元素的编号应当在[l+1,r]中,并且由搜索树的性质,在根的左子树上的值都小于根,右子树上的值大于等于根,那么容易确定出左右子树了。
之后模拟后续遍历:即先递归搜素左右子树,之后再输出当前节点处的值。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
#define INF 0x3f3f3f3f
#define EPS 1e-5
#define pi cos(-1)
const int N_MAX = + ;
int n,pos;
bool is_mirror;
vector<int>pre,post;
void dfs(const int& l, const int& r) {//找出[l,r]区间范围的根以及其左右子树
if (l > r)return;
int root = pre[pos++];
int i = l + , j = r;
if (!is_mirror) {//不是镜像,左子树上的值要比root小,右子树上的值大于等于root
while (i <= r&&root>pre[i])i++;
while (j>l&&root <= pre[j])j--;
}
else {
while (i <= r&&root <= pre[i])i++;
while (j >l&&root> pre[j])j--;
}
if (i - j != )return;//如果不是搜索树不满足条件 dfs(l + , j);
dfs(i, r); post.push_back(root);
} int main() {
scanf("%d", &n);
pre.resize(n);
for (int i = ; i < n;i++) {
scanf("%d",&pre[i]);
}
pos = ;
is_mirror = ;
dfs(, n-);
if (post.size()!=n) {
pos = ;
post.clear();
is_mirror = ;
dfs(, n-);
}
if (post.size() == n) {
puts("YES");
for (int i = ; i <n;i++) {
cout << post[i];
if (i + == n)cout << endl;
else cout << " ";
} }
else {
puts("NO");
}
pre.clear(); return ;
}
如果知道后序遍历,让你判断是否是搜索树,如果是,输出前序遍历,方法也类似,贴一下代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<iomanip>
#include<map>
#include<stack>
#include<set>
#include<queue>
#include<sstream>
using namespace std;
#define N_MAX 100000+2
#define INF 0x3f3f3f3f
struct Node {
int key=INF, left, right;
Node() {}
Node(int key,int left,int right):key(key),left(left),right(right) {}
}node[N_MAX];
int n,cnt=n-;
vector<int>pre,post;
bool ok = ;
void dfs(int n, int l, int r, bool is_mirror) {
if (l > r)return;
int root = post[cnt--];
int i = l, j = r-;
if (!is_mirror) {
while (i < r&&post[i] <root) i++;
while (j >= l&&post[j] >= root)j--;
}
else {
while (i < r&&post[i] >= root) i++;
while (j >= l&&post[j] < root)j--;
}
if (i - j != ) {
ok = ; return;
}
node[n] = Node(root, * n + , * n + );
dfs(*n+,i, r-,is_mirror);
dfs(*n+,l, j,is_mirror);//!!!
} void preorder(int n) {
pre.push_back(node[n].key);
if (node[*n+].key != INF)preorder(node[n].left);
if (node[*n+].key != INF)preorder(node[n].right);
} int main() {
while (cin >> n) {
post.resize(n);
for (int i = ; i < n; i++)cin >> post[i];
ok = ; cnt = n-;
dfs(,, n - , );
if (!ok) {
ok = ; cnt = n-;
dfs(,, n - , );
if (!ok) {
puts("NO");
}
}
if (ok) {
preorder();
puts("YES");
for (int i = ; i < pre.size(); i++)
printf("%d%c", pre[i], i + == pre.size() ? '\n' : ' ');
}
}
return ;
}
pat 团体天梯赛 L2-004. 这是二叉搜索树吗?的更多相关文章
- PAT天梯赛练习题 L3-010. 是否完全二叉搜索树(完全二叉树的判断)
L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜 ...
- 天梯赛练习 L3-010 是否完全二叉搜索树 (30分) 数组建树模拟
题目分析: 本题的要求是将n个数依次插入一个空的二叉搜索树(左大右小,且没有重复数字),最后需要输出其层次遍历以及判断是否是完全二叉搜索树,通过观察我们发现, 如果这个树是用数组建立的,那么最后输出的 ...
- pat 团体天梯赛 L3-007. 天梯地图
L3-007. 天梯地图 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 本题要求你实现一个天梯赛专属在线地图,队员输入自己学校 ...
- pat 团体天梯赛 L3-015. 球队“食物链”
L3-015. 球队“食物链” 时间限制 1000 ms 内存限制 262144 kB 代码长度限制 8000 B 判题程序 Standard 作者 李文新(北京大学) 某国的足球联赛中有N支参赛球队 ...
- pat 团体天梯赛 L1-039. 古风排版
L1-039. 古风排版 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 中国的古人写文字,是从右向左竖向排版的.本题就请你编写 ...
- pat 团体天梯赛 L2-012. 关于堆的判断
L2-012. 关于堆的判断 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的小顶堆H[] ...
- pat 团体天梯赛 L3-010. 是否完全二叉搜索树
L3-010. 是否完全二叉搜索树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 将一系列给定数字顺序插入一个初始为空的二叉搜 ...
- pat 团体天梯赛 L3-009. 长城
L3-009. 长城 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 邓俊辉(清华大学) 正如我们所知,中国古代长城的建造是为了抵御外 ...
- pat 团体天梯赛 L2-011. 玩转二叉树
L2-011. 玩转二叉树 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜 ...
- pat 团体天梯赛 L2-010. 排座位
L2-010. 排座位 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位. ...
随机推荐
- c++ 程序设计question 001:我们的开发工具是什么?
我们使用的开发工具是dev cpp (c plus plus),这是一个集成开发环境,我们称之为IDE(integrated development environment)
- jrtplib移植
jrtplib版本:3.11.1 jthread版本:1.3.3 libsrtp版本:1.6.0 jrtplib库有两种编译方式: 1. 使能jthread编译,此方式可使jrtplib自动在后台轮询 ...
- mysql 索引的统计
查看一个库里面没有使用过的索引select object_type,object_schema,object_name,index_name,count_star,count_read,COUNT_F ...
- react与微信小程序
由组员完成 原文链接 都说react和微信小程序很像,但是像在什么部分呢,待我稍作对比. 生命周期 1.React React的生命周期在16版本以前与之后发生了重大变化,原因在于引入的React F ...
- 开发监测keepalived裂脑的脚本
检测思路:在备节点上执行脚本,如果可以ping通主节点并且备节点有VIP就报警,让人员介入检查是否裂脑. 在LB02备节点上开发脚本并执行: [root@lb02 ~]# cat /server/sc ...
- Python知识点入门笔记——特色数据类型(函数)
函数的定义 def 函数名(形式参数): 函数体 [return 返回值] def是系统的关键字. 如果是自定义函数,函数名要复合变量命名规则,并且不能是系统关键字(jupyter中,打出系统关键字是 ...
- docker 学习(1)
Docker与容器和虚拟机 Docker跟虚拟机有什么区别啊?这个问题可以拆成两部分.因为Docker并不是什么完全独创的技术,而是属于很早便有了的容器技术,所以第一个问题就是容器与虚拟机的区别?同属 ...
- Codeforces Round #524 (Div. 2) C. Masha and two friends 思路
题目:题目链接 思路:直接计数显然是不好处理的,但分情况讨论只要不写错这题是一定可以出的,但这样基本做完这个题就没时间做其他题了,但当时我就这么蠢的这样做了,比赛一个半小时的时候突然发现一个似乎可行的 ...
- Codeforces Round #462 (Div. 2) D. A Determined Cleanup
D. A Determined Cleanup time limit per test1 second memory limit per test256 megabytes Problem Descr ...
- 二分答案:Poweroj2461-入门基础之二分答案(二分法的应用)
传送门:点击打开链接 入门基础之二分答案 Time Limit: 1000 MS Memory Limit: 65536 KBTotal Submit: 179 Accepted: 33 Page V ...