PAT甲级【2019年3月考题】——A1159 Structure_of_a_BinaryTree【30】
Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, a binary tree can be uniquely determined.
Now given a sequence of statements about the structure of the resulting tree, you are supposed to tell if they are correct or not. A statment is one of the following:
A is the root
A and B are siblings
A is the parent of B
A is the left child of B
A is the right child of B
A and B are on the same level
It is a full tree
Note:
Two nodes are on the same level, means that they have the same depth.
A full binary tree is a tree in which every node other than the leaves has two children.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are no more than 103 10^310
3
and are separated by a space.
Then another positive integer M (≤30) is given, followed by M lines of statements. It is guaranteed that both A and B in the statements are in the tree.
Output Specification:
For each statement, print in a line Yes if it is correct, or No if not.
Sample Input:
9
16 7 11 32 28 2 23 8 15
16 23 7 32 11 2 28 15 8
7
15 is the root
8 and 2 are siblings
32 is the parent of 11
23 is the left child of 16
28 is the right child of 2
7 and 11 are on the same level
It is a full tree
Sample Output:
Yes
No
Yes
No
Yes
Yes
Yes
【声明】
由于此题还未上PAT官网题库,故没有测试集,仅仅是通过了样例,若发现错误,感谢留言指正。
Solution:
这道题不难,先通过后序和中序重构整颗二叉树,在重构时,使用hash表来存储每个节点值对应的节点,这样就可以解决后面询问是不是父节点和左右子节点的问题。
然后使用DFS来遍历整棵树,得到每个节点的深度值,其中记得记录每个节点的姐妹节点是谁,并进行判断是不是完整二叉树。
到此,对于题目中的7个问题都有相应的记录进行解决
唯一麻烦的是,对于问题的处理,题目是输入一整句话,那么判断属于哪个问题和将其中的关键数字取出来就比较麻烦,我是使用string中的find来判断属于哪个问题,并使用循环来获取数字,当然你也可以使用istringstream函数进行切割获取数据。
#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <unordered_map>
using namespace std;
struct Node
{
int val;
Node *l, *r;
Node(int a = ) :val(a), l(nullptr), r(nullptr) {}
};
int n, m;
bool isfullTree = true;
vector<int>post, in, siblings(, -), level(, -);
unordered_map<int, Node*>map;
Node* creatTree(int inL, int inR, int postL, int postR)//重建二叉树
{
if (inL > inR)
return nullptr;
Node *root = new Node(post[postR]);
map[root->val] = root;//记录节点对应的key值
int k = inL;
while (k <= inR && in[k] != post[postR])++k;
int nums = k - inL;
root->l = creatTree(inL, k - , postL, postL + nums - );
root->r = creatTree(k + , inR, postL + nums, postR - );
return root;
}
void DFS(Node *root, int L)
{
if (root == nullptr)
return;
if ((root->l == nullptr && root->r) || (root->r == nullptr && root->l))
isfullTree = true;//不是完全二叉树
level[root->val] = L;//记录层数
if (root->l&& root->r)//记录姐妹节点
{
siblings[root->l->val] = root->r->val;
siblings[root->r->val] = root->l->val;
}
DFS(root->l, L + );
DFS(root->r, L + );
}
vector<int> getNumber(const string &str, bool isOneNumber)//获取数据
{
vector<int>res;
int a = ;
for (int i = ; i < str.length(); ++i)
{
if (isdigit(str[i]))
a = a * + str[i] - '';
else if (a > )
{
res.push_back(a);
a = ;
if (isOneNumber || res.size() == )//就输出一个字符就行
break;
}
}
if (!isOneNumber && res.size() < )//获取处于最后的数字
res.push_back(a);
return res;
}
int main()
{
cin >> n;
post.resize(n);
in.resize(n);
for (int i = ; i < n; ++i)
cin >> post[i];
for (int i = ; i < n; ++i)
cin >> in[i];
Node *root = creatTree(, n - , , n - );
DFS(root, );//获取层数
cin >> m;
getchar();
while (m--)
{
string str;
getline(cin, str);
if (str.find("root", ) != -)//查询根节点
{
vector<int>res = getNumber(str, true);
if (root->val == res[])
printf("Yes\n");
else
printf("No\n");
}
else if (str.find("siblings", ) != -)//查询姐妹节点
{
vector<int>res = getNumber(str, false);
if (siblings[res[]] == res[])
printf("Yes\n");
else
printf("No\n");
}
else if (str.find("parent", ) != -)//查询父节点
{
vector<int>res = getNumber(str, false);
if ((map[res[]]->l && map[res[]]->l->val == res[]) ||
(map[res[]]->r && map[res[]]->r->val == res[]))
printf("Yes\n");
else
printf("No\n");
}
else if (str.find("left", ) != -)//左节点
{
vector<int>res = getNumber(str, false);
if (map[res[]]->l && map[res[]]->l->val == res[])
printf("Yes\n");
else
printf("No\n");
}
else if (str.find("right", ) != -)//右节点
{
vector<int>res = getNumber(str, false);
if (map[res[]]->r && map[res[]]->r->val == res[])
printf("Yes\n");
else
printf("No\n");
}
else if (str.find("level", ) != -)//同样的深度
{
vector<int>res = getNumber(str, false);
if (level[res[]]==level[res[]])
printf("Yes\n");
else
printf("No\n");
}
else if (str.find("full", ) != -)//是不是完整二叉树
{
if (isfullTree)
printf("Yes\n");
else
printf("No\n");
}
}
return ;
}
我的代码有点繁琐,后然我逛博客发现了一个更简便的字符处理函数sscanf,还有就是由于重构二叉树的同时就是一个DFS的过程,这样我们就可以将其深度值得到。当然,我感觉我的代码还是有点优点的,不是么 ^_^.
附带博主代码:
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<string>
#include<cstring>
#include<unordered_map>
#include<unordered_set>
using namespace std;
const int maxn=;
const int INF=0x3f3f3f3f;
unordered_map<int,int> level,parents;
struct node {
int data;
int layer;
node *lchild,*rchild;
};
vector<int> post,in;
node* newNode(int data,int layer) {
node* root=new node;
root->data=data;
root->layer=layer;
level[data]=layer;
root->lchild=root->rchild=NULL;
return root;
}
bool flag=true;
node* create(int parent,int postLeft,int postRight,int inLeft,int inRight,int layer) {
if(postLeft>postRight) return NULL;
node* root=newNode(post[postRight],layer);
parents[root->data]=parent;
int index=inLeft;
while(in[index]!=root->data) index++;
int numLeft=index-inLeft;
root->lchild=create(root->data,postLeft,postLeft+numLeft-,inLeft,index-,layer+);
root->rchild=create(root->data,postLeft+numLeft,postRight-,index+,inRight,layer+);
//如果有叶子,就必须有两片叶子
if((root->lchild || root->rchild ) && (!root->lchild || !root->rchild)) flag=false;
return root;
}
int main() {
int n,m;
unordered_map<int,int> ppos,ipos;
scanf("%d",&n);
post.resize(n);
in.resize(n);
for(int i=; i<n; i++) {
scanf("%d",&post[i]);
ppos[post[i]]=i;
}
for(int i=; i<n; i++) {
scanf("%d",&in[i]);
ipos[in[i]]=i;
}
node* root = create(n-,,n-,,n-,);
scanf("%d\n",&m);
string ask;
for(int i=; i<m; i++) {
getline(cin,ask);
int num1=,num2=;
if(ask.find("root")!=string::npos) {
sscanf(ask.c_str(),"%d is the root",&num1);
if(ppos[num1]==n-) puts("Yes");
else puts("No");
} else if(ask.find("siblings")!=string::npos) {
sscanf(ask.c_str(),"%d and %d are siblings",&num1,&num2);
if(level[num1]==level[num2] && parents[num1]==parents[num2]) puts("Yes");
else puts("No");
} else if(ask.find("parent")!=string::npos) {
sscanf(ask.c_str(),"%d is the parent of %d",&num1,&num2);
if(parents[num2]==num1) puts("Yes");
else puts("No");
} else if(ask.find("left")!=string::npos) {
sscanf(ask.c_str(),"%d is the left child of %d",&num1,&num2);
if(parents[num1]==num2 && ipos[num1]<ipos[num2]) puts("Yes");
else puts("No");
} else if(ask.find("right")!=string::npos) {
sscanf(ask.c_str(),"%d is the right child of %d",&num1,&num2);
if(parents[num1]==num2 && ipos[num1]>ipos[num2]) puts("Yes");
else puts("No");
} else if(ask.find("same")!=string::npos) {
sscanf(ask.c_str(),"%d and %d are on the same level",&num1,&num2);
if(level[num1]==level[num2]) puts("Yes");
else puts("No");
} else if(ask.find("full")!=string::npos) {
if(flag) puts("Yes");
else puts("No");
}
}
return ;
}
PAT甲级【2019年3月考题】——A1159 Structure_of_a_BinaryTree【30】的更多相关文章
- 2019年3月29日至30日深圳共创力《成功的产品经理DNA》在深圳公开课成功举办
2019年3月29至30日,在深圳南山区中南海滨大酒店10楼行政厅,由深圳市共创力企业管理咨询有限公司举办的<成功的产品经理DNA>公开课成功举办,此次公开课由深圳市共创力咨询资深讲师冯老 ...
- PAT甲级【2019年3月考题】——A1157 Anniversary【25】
Zhejiang University is about to celebrate her 122th anniversary in 2019. To prepare for the celebrat ...
- PAT甲级【2019年9月考题】——A1164 DijkstraSequence【30】
7-4 Dijkstra Sequence (30 分) Dijkstra's algorithm is one of the very famous greedy algorithms. It is ...
- PAT甲级【2019年9月考题】——A1163 PostfixExpression【25】
7-3 Postfix Expression (25 分) Given a syntax tree (binary), you are supposed to output the correspon ...
- PAT甲级【2019年9月考题】——A1162 MergingLinkedLists【25】
7-2 Merging Linked Lists (25 分) Given two singly linked lists L 1 =a 1 →a 2 →...→a n−1 →a n L1=a1→a ...
- PAT甲级【2019年9月考题】——A1160 Forever【20】
7-1 Forever (20 分) "Forever number" is a positive integer A with K digits, satisfying the ...
- PAT甲级【2019年3月考题】——A1158 TelefraudDetection【25】
Telefraud(电信诈骗) remains a common and persistent problem in our society. In some cases, unsuspecting ...
- PAT甲级【2019年3月考题】——A1156 SexyPrimes【20】
Sexy primes are pairs of primes of the form (p, p+6), so-named since “sex” is the Latin word for “si ...
- PAT甲级2019冬季考试题解
A Good In C纯模拟题,用string数组读入数据,注意单词数量的判断 #include<bits/stdc++.h> using namespace std; ; ][]; in ...
随机推荐
- 洛谷 P1546 最短网络 Agri-Net(最小生成树)
题目链接 https://www.luogu.org/problemnew/show/P1546 说过了不复制内容了 显然是个最小生成树. 解题思路 prim算法 Kruskal算法 prim算法很直 ...
- python学习二十一天文件可读,可写,可执行的操作
文件无非是可读,可写,可执行的操作,分别对应的模式 r ,w,x,只读模式,只写模式,只执行模式,a模式为追加模式,实际也是写操作模式,r+,w+,a+ 可读写模式,下面详细说模式的用法 1,文件的模 ...
- PEP8规范总结
PEP8规范总结 代码编排 1 缩进.4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格. 2 每行最大长度79,换行可以使用反斜杠,最好使用圆括号.换行点要在操作符的 ...
- nginx的4层负载均衡配置
前言:所谓四层就是基于IP+端口的负载均衡:七层就是基于URL等应用层信息的负载均衡:同理,还有基于MAC地址的二层负载均衡和基于IP地址的三层负载均衡. 换句换说,二层负载均衡会通过一个虚拟MAC地 ...
- Ajax爬取豆瓣电影目录(Python)
下面的分析相当于一个框架,搞懂之后,对于类似的文字爬取,我们也可以实现.就算不能使用Ajax方法,我们也能够使用相同思想去爬取我们想要的数据. 豆瓣电影排行榜分析 网址:https://movie.d ...
- Spring Cloud Contract简介
转载:https://www.jianshu.com/p/e3277824a10a 和dummy service一样 Spring Cloud Contract是个啥? Spring Cloud Co ...
- 没有dockerfile的情况下如何查看docker的镜像信息
前言 参考资料 https://baijiahao.baidu.com/s?id=1564406878758073&wfr=spider&for=pc 很实用的功能哈.. 步骤 1.先 ...
- Java虚拟机(JVM)与垃圾回收机制(GC)的详解
一.JVM结构 根据<java虚拟机规范>规定,JVM的基本结构一般如下图所示: 从左图可知,JVM主要包括四个部分: 1.类加载器(ClassLoader):在JVM启动时或者在类运行时 ...
- linux下的软链接与硬链接
在 Linux 底下的连结档有两种,一种是类似 Windows 的快捷方式功能的文件,可以让你快速的链接到目标文件(或目录);这种链接称为软链接. 另一种则是透过文件系统的 inode 连结来产生新档 ...
- linux清除文件内容
#以下方式清空文件大小为0 cat /dev/null > catalina.out清除日志文件 $ : > filename $ > filename #以下方式清空文件大小为1 ...