PTA 笛卡尔树
笛卡尔树 (25 分)
笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2。首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大。其次所有结点的K2关键字满足优先队列(不妨设为最小堆)的顺序要求,即该结点的K2值比其子树中所有结点的K2值小。给定一棵二叉树,请判断该树是否笛卡尔树。
输入格式:
输入首先给出正整数N(≤1000),为树中结点的个数。随后N行,每行给出一个结点的信息,包括:结点的K1值、K2值、左孩子结点编号、右孩子结点编号。设结点从0~(N-1)顺序编号。若某结点不存在孩子结点,则该位置给出−1。
输出格式:
输出YES如果该树是一棵笛卡尔树;否则输出NO。
输入样例1:
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 21 -1 4
15 22 -1 -1
5 35 -1 -1
输出样例1:
YES
输入样例2:
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 11 -1 4
15 22 -1 -1
50 35 -1 -1
输出样例2:
NO
笛卡尔树的性质:
1.如果只含key值,不含value值的话,此树就像是一颗二叉搜索树。性质和二叉搜索树的性质是一样的,从左子树到右子树依次变大。而val值的意思正好和key值的意思相反。
2.笛卡尔树的以key值为准,中序遍历出的key值必须是从小到大的(不能相等)。
#include<iostream>
#include<cstdio>
#include<vector> using namespace std; struct node
{
int key;
int val;
int lchild;
int rchild;
}a[]; int vis[],flag,ans[],cnt=; void fun(int root)
{
if(!flag) //减少不必要的递归,节约时间
return ;
if(a[root].lchild!=-) //如果左孩子不为-1,则进行下一步操作
{
int left=a[root].lchild;
if(a[left].key>=a[root].key) //假如该位置的前一个左孩子大于或者等于该位置的key值 //
{ //则将flag赋值为flase
flag=;
return ;
}
fun(left);
}
if(a[root].rchild!=-) //同上,就是该位置的前一个右孩子小于或者等于该位置的val值
{
int right=a[root].rchild;
if(a[right].val<=a[root].val)
{
flag=;
return ;
}
fun(right);
}
} void in_order(int root)//中序遍历此树
{
if(root!=-)
{
in_order(a[root].lchild);
ans[cnt++]=a[root].key;
in_order(a[root].rchild);
}
} int main()
{
int n;
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%d%d%d%d",&a[i].key,&a[i].val,&a[i].lchild,&a[i].rchild);
if(a[i].lchild!=-) //记录所有出现的结点,没出现的那个节点就是根节点
vis[a[i].lchild]=;
if(a[i].rchild!=-)
vis[a[i].rchild]=;
}
int root=-;
for(int i=;i<n;i++) //找出根节点
if(!vis[i])
{
root=i;
break; //记住跳出,减少没有必要的循环
}
if(root==-) //判断此树是否为空树
{
printf("YES\n");
return ;
}
flag=; //如果为true则是笛卡尔树,否则不是
fun(root); //递归判断此树
in_order(root); //中序遍历
for(int i=;i<cnt-;i++) //判断中序遍历出的key值是否符合二叉搜索树的性质(从小到大)
if(ans[i]>=ans[i+])
{
flag=;
break;
}
if(flag)
printf("YES\n");
else
printf("NO\n");
return ;
}
PTA 笛卡尔树的更多相关文章
- codevs2178 表达式运算Cuties[笛卡尔树]
2178 表达式运算Cuties 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 大师 Master 题解 查看运行结果 题目描述 Description 给出一个表达 ...
- POJ 2559 Largest Rectangle in a Histogram ——笛卡尔树
[题目分析] 本来是单调栈的题目,用笛卡尔树可以快速的水过去. 把每一个矩阵看成一个二元组(出现的顺序,高度). 然后建造笛卡尔树. 神奇的发现,每一个节点的高度*该子树的大小,就是这一块最大的子矩阵 ...
- NOIP2011pj表达式的值[树形DP 笛卡尔树 | 栈 表达式解析]
题目描述 对于1 位二进制变量定义两种运算: 运算的优先级是: 先计算括号内的,再计算括号外的. “× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算.例如:计算表达式A⊕B × ...
- POJ 2201 Cartesian Tree ——笛卡尔树
[题目分析] 构造一颗笛卡尔树,然后输出这棵树即可. 首先进行排序,然后用一个栈维护最右的树的节点信息,插入的时候按照第二关键字去找,找到之后插入,下面的树成为它的左子树即可. 然后插入分三种情况讨论 ...
- POJ 1785 Binary Search Heap Construction(裸笛卡尔树的构造)
笛卡尔树: 每个节点有2个关键字key.value.从key的角度看,这是一颗二叉搜索树,每个节点的左子树的key都比它小,右子树都比它大:从value的角度看,这是一个堆. 题意:以字符串为关键字k ...
- [BZOJ]4199: [Noi2015]品酒大会(后缀数组+笛卡尔树)
Time Limit: 10 Sec Memory Limit: 512 MB Description Input Output Sample Input 10 ponoiiipoi 2 1 4 7 ...
- [模板] 笛卡尔树 && RMQ
话说我noip之前为什么要学这种东西... 简介 笛卡尔树(Cartesian Tree) 是一种二叉树, 且同时具有以下两种性质: 父亲节点的值大于/小于子节点的值; 中序遍历的结果为原序列. 笛卡 ...
- BZOJ.2616.SPOJ PERIODNI(笛卡尔树 树形DP)
BZOJ SPOJ 直观的想法是构建笛卡尔树(每次取最小值位置划分到两边),在树上DP,这样两个儿子的子树是互不影响的. 令\(f[i][j]\)表示第\(i\)个节点,放了\(j\)个车的方案数. ...
- BZOJ2616 SPOJ PERIODNI(笛卡尔树+树形dp)
考虑建一棵小根堆笛卡尔树,即每次在当前区间中找到最小值,以最小值为界分割区间,由当前最小值所在位置向两边区间最小值所在位置连边,递归建树.那么该笛卡尔树中的一棵子树对应序列的一个连续区间,且根的权值是 ...
随机推荐
- 你不知道的css各类布局(三)之自适应布局
自适应布局 概念 自适应布局(Adaptive Layout)是对凡是有自适应特性的一类布局的统称 自适应布局使用media query来检测当前浏览器的宽度进而通过CSS样式调整页面大小.自适应布局 ...
- JS基础_对象的简介、对象的基本操作
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- JS基础_打印出1-100之间所有的质数
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- openlayers 地图移动缩放动画
map.getView().animate({ // 只设置需要的属性即可 center: [data.jd, data.wd], // 中心点 zoom: 11, // 级别 rotation: u ...
- Windows去除开始菜单图标背景
1.开始菜单图标右键找到目标程序的存储目录. 2.删除目录下的目标程序名+.VisualElementsManifest.xml的文件. 3.开始菜单图标右键找到图标的存储目录,取消开始屏幕固定并删除 ...
- 02-【servlet】
1.什么是Servlet Servlet是JavaWeb的三大组件之一[Servlet,Filter,Listener],它属于动态资源.Servlet的作用是处理请求,服务器会把接收到的请求交给Se ...
- ARM cortex-version
cortex-M\A\R M microcontroller 微控制器 就是单片机 A application 应用及处理器 就是手机平板电脑等 R realtime 实时处理器 响应 ...
- Hive(七)Hive参数操作和运行方式
Hive参数操作和运行方式 1.Hive参数操作 1.hive参数介绍 hive当中的参数.变量都是以命名空间开头的,详情如下表所示: 命名空间 读写权限 含义 hiveconf 可读写 hive ...
- shell命令学习记录
id id会显示用户以及所属群组的实际与有效ID hostname 用来显示或者设置主机名(show or set the system’s host name).环境变量HOSTNAME也保存了当前 ...
- 调用libusb_control_transfer 出错,返回-8
写入 0x81读出 0x01 对USB输出端点进行初始化,包括端点地址.传输类型和最大包长度 注意一下,USB初始化时,也有读/写之分. 写入: cyusb_bulk_transfer(writeha ...