PTA L2-004 这是二叉搜索树吗?-判断是否是对一棵二叉搜索树或其镜像进行前序遍历的结果 团体程序设计天梯赛-练习集

L2-004 这是二叉搜索树吗? (25 分)

一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,

  • 其左子树中所有结点的键值小于该结点的键值;
  • 其右子树中所有结点的键值大于等于该结点的键值;
  • 其左右子树都是二叉搜索树。

所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。

给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。

输入格式:

输入的第一行给出正整数 N(≤)。随后一行给出 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

因为前面写了二叉树的,所以这道题打算也用那种思路,写是写出来了,但是感觉怪怪的。

我建树是保存的下标编号,因为数可能是一样的,但是下标编号是唯一的。

建完树之后,写了个bfs搜了一下左右节点,发现好像也没毛病,但是自己想的一个样例过不了,肯定是错的代码,应该是后台样例比较水,所以满分水过了。。。

代码写的奇丑无比,但是还是希望有好心人能帮我想想我的代码哪里要改才能改对,过不了的样例:

2

2 1

输出应该为

YES

1 2

我的代码跑不出来。

后面看了一下别人的题解,发现还是别人的思路更简洁好实现一些,学到了,我这个弟弟。

先贴一下我的代码,不要学我的代码,有bug的,找不出来什么问题。。。

代码:

  1 //L2-004 这是二叉搜索树吗?
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 typedef long long ll;
  5 const int maxn=1e5+10;
  6 const int inf=0x3f3f3f3f;
  7
  8 int pre[maxn];
  9 int n,flag=0;
 10
 11 struct node{
 12     int l,r;
 13 }tree[maxn];
 14
 15 int buildmin(int l,int r)
 16 {
 17     if(l>r) return 0;
 18     if(r==-1) return 0;
 19     int rt=pre[l];
 20     int p1=r;
 21     while(pre[p1]>=rt){
 22         if(p1==l) break;
 23         p1--;
 24     }
 25     int minn=inf,pos;
 26     for(int i=p1;i>l;i--){
 27         if(minn>pre[i]){
 28             minn=pre[i];
 29             pos=i;
 30         }
 31     }
 32     for(int i=pos;i>l;i--){
 33         if(pre[i]>=rt){
 34             flag=1;break;
 35         }
 36     }
 37     if(flag==1){
 38         buildmin(0,-1);
 39     }
 40 //    cout<<pre[p1]<<endl;
 41     else{
 42         if(p1!=l){
 43             tree[l].l=buildmin(l+1,p1);
 44             tree[l].r=buildmin(p1+1,r);
 45         }
 46         else{
 47            tree[l].r=buildmin(p1+1,r);
 48         }
 49         return l;
 50     }
 51 }
 52
 53 int buildmax(int l,int r)
 54 {
 55     if(l>r) return 0;
 56     if(r==-1) return 0;
 57     int rt=pre[l];
 58     int p1=r;
 59     while(pre[p1]<rt){
 60         p1--;
 61     }
 62     for(int i=p1;i>l;i--){
 63         if(pre[i]<rt){
 64             flag=1;break;
 65         }
 66     }
 67     if(flag==1){
 68         buildmax(0,-1);
 69     }
 70 //    cout<<pre[p1]<<endl;
 71     else{
 72         if(p1!=r){
 73             tree[l].l=buildmax(l+1,p1);
 74             tree[l].r=buildmax(p1+1,r);
 75         }
 76         else{
 77             tree[l].l=buildmax(l+1,p1);
 78         }
 79         return l;
 80     }
 81 }
 82
 83 void bfs(int x)
 84 {
 85     vector<int> vec;
 86     queue<int> que;
 87     que.push(x);
 88     while(!que.empty()){
 89         int ret=que.front();
 90         que.pop();
 91         if(ret==0) break;
 92         vec.push_back(ret);
 93         if(tree[ret].l!=0){
 94             que.push(tree[ret].l);
 95         }
 96         if(tree[ret].r!=0){
 97             que.push(tree[ret].r);
 98         }
 99     }
100     int l=vec.size();
101     for(int i=0;i<l;i++)
102         cout<<pre[vec[i]]<<" ";
103     cout<<endl;
104 }
105
106 vector<int> vec;
107
108 int behorder(int x)
109 {
110     if(tree[x].l==0&&tree[x].r==0){
111         if(pre[x]!=0)
112             vec.push_back(pre[x]);
113         return 0;
114     }
115     behorder(tree[x].l);
116     behorder(tree[x].r);
117     vec.push_back(pre[x]);
118 }
119
120 void print()
121 {
122     int l=vec.size();
123     for(int i=0;i<l-1;i++)
124         cout<<vec[i]<<" ";
125     cout<<vec[l-1]<<endl;
126 }
127
128 int main()
129 {
130     scanf("%d",&n);
131     for(int i=1;i<=n;i++)
132         scanf("%d",&pre[i]);
133 //        cout<<"23333333333"<<endl;
134     if(pre[2]<pre[1]){
135         buildmin(1,n);
136         if(flag==1) cout<<"NO"<<endl;
137         else{
138 //            bfs(1);
139             cout<<"YES"<<endl;
140             behorder(1);
141             print();
142         }
143     }
144     else{
145         buildmax(1,n);
146         if(flag==1) cout<<"NO"<<endl;
147         else{
148 //            bfs(1);
149             cout<<"YES"<<endl;
150             behorder(1);
151             print();
152         }
153     }
154 //    for(int i=1;i<=n;i++)
155 //        cout<<tree[i].l<<" "<<tree[i].r<<endl;
156 //
157 ////    else buildmax(1,n);
158 //    behorder();
159
160 }

学的别人的思路:

代码:

 1 //L2-004 这是二叉搜索树吗?
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 typedef long long ll;
 5 const int maxn=1e5+10;
 6 const int inf=0x3f3f3f3f;
 7
 8 int n;
 9 int isMirror=0;
10 int pre[maxn];
11 vector<int> vec;
12
13 int build(int l,int r)
14 {
15     if(l>r) return 0;
16     int rt=pre[l];
17     int p1=l+1,p2=r;
18     if(!isMirror){
19         while(p1<=r&&rt>pre[p1]) p1++;
20         while(p2>l&&rt<=pre[p2]) p2--;
21     }
22     else{
23         while(p1<=r&&rt<=pre[p1]) p1++;
24         while(p2>l&&rt>pre[p2]) p2--;
25     }
26     if(p1-p2!=1) return 0;
27     build(l+1,p2);//按照后序遍历建树
28     build(p1,r);
29     vec.push_back(rt);
30 }
31
32 int main()
33 {

先这样。

原文地址:https://www.cnblogs.com/ZERO-/p/10624923.html

时间: 2024-08-04 07:19:35

PTA L2-004 这是二叉搜索树吗?-判断是否是对一棵二叉搜索树或其镜像进行前序遍历的结果 团体程序设计天梯赛-练习集的相关文章

PAT 团体程序设计天梯赛-练习集 L1-017. 到底有多二

一个整数“犯二的程度”定义为该数字中包含2的个数与其位数的比值.如果这个数是负数,则程度增加0.5倍:如果还是个偶数,则再增加1倍.例如数字“-13142223336”是个11位数,其中有3个2,并且是负数,也是偶数,则它的犯二程度计算为:3/11*1.5*2*100%,约为81.82%.本题就请你计算一个给定整数到底有多二. 输入格式: 输入第一行给出一个不超过50位的整数N. 输出格式: 在一行中输出N犯二的程度,保留小数点后两位. 输入样例: -13142223336 输出样例: 81.8

PTA L2-023 图着色问题-前向星建图 团体程序设计天梯赛-练习集

L2-023 图着色问题 (25 分) 图着色问题是一个著名的NP完全问题.给定无向图,,问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解. 输入格式: 输入在第一行给出3个整数V(0).E(≥)和K(0),分别是无向图的顶点数.边数.以及颜色数.顶点和颜色都从1到V编号.随后E行,每行给出一条边的两个端点的编号.在图的信息给出之后,给出了一个正整数N(≤),是待

团体程序设计天梯赛-练习集(二)

L1-041 寻找250 (10分) https://pintia.cn/problem-sets/994805046380707840/problems/994805089657536512 #include <cstdio> #include <iostream> using namespace std; int main() { int n,flag=0; int num=1; int value; while(scanf("%d",&n)!=EO

PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/problem-sets/994805046380707840/problems 目录 (点击对应题目即可进入相应题解--小声BB--) L1-001 Hello World (5 分) L1-002 打印沙漏 (20 分) L1-003 个位数统计 (15 分) L1-004 计算摄氏温度 (5

PTA 团体程序设计天梯赛 L3-020 至多删三个字符

$f[i][j]$表示到第$i$个字符,已经删去了$j$个字符的方案数. 显然的转移: $f[i][j] = f[i - 1][j] + f[i - 1][j - 1]$ 但是这样会有重复,我们考虑什么情况会重复. 比如说:'aabab'中的'bab',我们删去'ba',得到'aab',删去'ab'得到'aab',两者是相同的 1 2 3 4 5 a a b a b 我们假设之前的每一位存的都是没有重复的方案数 就刚才的情况,我们发现当我们递推到第$5$个位置的时候,删去第三位和第四位的'ba'

『ACM C++』 PTA 天梯赛练习集L1 | 001-006

应师兄要求,在打三月底天梯赛之前要把PTA上面的练习集刷完,所以后面的时间就献给PTA啦~ 后面每天刷的题都会把答案代码贡献出来,如果有好的思路想法也会分享一下~ 欢迎大佬提供更好的高效率算法鸭~ ------------------------------------------------L1-001---------------------------------------------------------- 这道超级简单的题目没有任何输入. 你只需要在一行中输出著名短句“Hello

『ACM C++』 PTA 天梯赛练习集L1 | 007-0011

真的是忙头晕了,学业.ACM打题.班级活动.自学新东西,哇这充实的大学~ ------------------------------------------------L1-007---------------------------------------------------------- 念数字 输入一个整数,输出每个数字对应的拼音.当整数为负数时,先输出fu字.十个数字对应的拼音如下: 0: ling 1: yi 2: er 3: san 4: si 5: wu 6: liu 7:

『ACM C++』 PTA 天梯赛练习集L1 | 016-017

今天开了两个大会,时间都给占掉了,就刷了两道题~ 明天加油!!! ------------------------------------------------L1-016---------------------------------------------------------- 查验身份证 一个合法的身份证号码由17位地区.日期编号和顺序编号加1位校验码组成.校验码的计算规则如下: 首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,

『ACM C++』 PTA 天梯赛练习集L1 | 018-020

终于一周有这么一天能够安静下来好好学习打打题,还是很美滋滋的哈哈~加油加油~ ------------------------------------------------L1-018---------------------------------------------------------- 大笨钟 微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉.不过由于笨钟自己作息也不是很规律,所以敲钟并不定时.一般敲钟的点数是根据敲钟时间而定的,如果正好在某个整点敲,那么“当