版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Flynn_curry/article/details/60962558
https://www.patest.cn/contests/gplt/L2-004
题意:给你一组前序遍历的结果,看是否能建成二叉搜索树或其镜像,若是则输出后序遍历输出。
思路:如果能构成,那就是hdu3999了,先建树然后遍历。关键在于如何判断不能构成。输入的序列已经知道根,所以从根dfs,遇到比根大的就是右子树,若右子树中出现比根小的,那么不能构成二叉搜索树。
这题一度写到我崩溃,先是以为树建错,甚至怀疑过pat不能用malloc,后来看了别人的居然是check部分错了。每次check的i值必须要初始化一个值,不然错误很难找啊。这位牛很巧妙的处理了这方面,直接用i中断出来递归,而不是像我一样再弄一个变量。。
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 1005;
typedef struct Tree
{
Tree *left;
Tree *right;
int val;
}Tree;
int seq[N];
Tree *root;
int cnt, n, kind;
bool check1(int l, int r)//检查是否为原树
{
if(l >= r) return true;
int i;
for(i = l+1; i <= r; i++)
{
if(seq[i]>=seq[l])
{
break;
}
}
for(int j = i; j <= r; j++)
{
if(seq[j]<seq[l]) return false;
}
return check1(l+1, i-1)&&check1(i, r);
}
bool check2(int l, int r)
{
if(l >= r) return true;
int i;
for(i = l+1; i <= r; i++)
{
if(seq[i]<seq[l])
{
break;
}
}
for(int j = i; j <= r; j++)
{
if(seq[j]>=seq[l]) return false;
}
return check2(l+1, i-1)&&check2(i, r);
}
Tree *creat(int num)
{
Tree *node = (Tree*)malloc(sizeof(Tree));
node->left = NULL;
node->right = NULL;
node->val = num;
return node;
}
Tree *insertt(Tree *node, int num)
{
if(node == NULL)
{
node = creat(num);
}
else
{
if(kind == 1)//是原树
{
if(num < node->val) node->left = insertt(node->left, num);
else if (num >= node->val) node->right = insertt(node->right, num);
}
else if(kind == 2)
{
if(num >= node->val) node->left = insertt(node->left, num);
else if (num < node->val) node->right = insertt(node->right, num);
}
}
return node;
}
void build(int len)
{
root = NULL;
cnt = 0;
for(int i = 0; i < len; i++)
{
int num = seq[i];
root = insertt(root, num);
}
}
void postorder(Tree *cur)
{
if(cur != NULL)
{
postorder(cur->left);
postorder(cur->right);
if(cnt==n-1) printf("%d\n", cur->val);
else
{
printf("%d ", cur->val);
cnt++;
}
}
}
int main()
{
// freopen("in.txt", "r", stdin);
while(~scanf("%d", &n))
{
if(n == 0)
{
printf("YES\n");
continue;
}
for(int i = 0; i < n; i++)
scanf("%d", &seq[i]);
kind = 0;
if(check1(0, n-1)) kind = 1;
else if(check2(0, n-1)) kind = 2;
if(kind == 0)
{
printf("NO\n");
continue;
}
build(n);
printf("YES\n");
postorder(root);
}
}