团体程序设计天梯赛-练习集-L2-004. 这是二叉搜索树吗?

这篇博客记录了作者在团体程序设计天梯赛中遇到的一道难题——L2-004. 这是二叉搜索树吗?题目要求通过递归方式,将输入序列划分并构建二叉搜索树,同时注意各种边界条件。作者提醒读者,虽然题目难度较低,但需要注意细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记录一个菜逼的成长。。

题目链接

虽然只是L2级,但是感觉比一些L3还要难写。。

其实就是建树的一个过程,如果可以把序列划分成两个部分,一部分的值都比这个节点小,另一部分的值都大于等于这个节点的值
对于每一个节点,都如此判断,递归进行。
这题要注意很多细节。
通不过的可以测试下
Sample1:
2
2 1
Sample2:
3
3 1 2

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define ALL(v) (v).begin(),(v).end()
#define cl(a,b) memset(a,b,sizeof(a))
#define pb push_back
typedef long long LL;
const int maxn = 2000 + 10;
int a[maxn],flag,vis[maxn];
struct node{
    int l,r,v;
}tree[maxn];
bool check1(int l,int r,int &pos)
{
    for( int i = l+1; i <= r; i++ ){
        if(a[i] >= a[l]){
            pos = i;
            for( int j = i; j <= r; j++ ){
                if(a[j] < a[l])return false;
            }
            return true;
        }
    }
    return true;
}
bool check2(int l,int r,int &pos)
{
    for( int i = l+1; i <= r; i++ ){
        if(a[i] < a[l]){
            pos = i;
            for( int j = i; j <= r; j++ ){
                if(a[j] >= a[l])return false;
            }
            return true;
        }
    }
    return true;
}
int ind,ok;
void build(int l,int r)
{
    if(flag || l > r)return ;
    tree[ind++].v = a[l];
    if(l == r)return ;
    int pos1 = 0,pos2 = 0;
    bool ret1 = check1(l,r,pos1);
    bool ret2 = check2(l,r,pos2);
    //cout<<ret1<<' '<<ret2<<' '<<pos1<<' '<<pos2<<endl;
    if(!ret1 && !ret2){
        flag = 1;
        return ;
    }

    if(!ok){
        if((ret1&&ret2) || (ret1&&!ret2))ok = 1;
        else ok = 2;
    }
    int num;
    if(ret1&&ret2)num = ok;
    else if(ret1&&!ret2)num = 1;
    else num = 2;
    if(num != ok){
        flag = 1;
        return ;
    }
    if(num == 1){
        tree[ind-1].l = l+1;
        tree[ind-1].r = pos1;
        build(l+1,pos1?pos1-1:r);
        build(pos1?pos1:r+1,r);
    }
    else {
        tree[ind-1].l = l+1;
        tree[ind-1].r = pos2;
        build(l+1,pos2?pos2-1:r);
        build(pos2?pos2:r+1,r);
    }
}
void post_print(int t)
{
    if(vis[t])return ;
    vis[t] = 1;
    post_print(tree[t].l);
    post_print(tree[t].r);
    if(flag)cout<<tree[t].v,flag = 0;
    else cout<<" "<<tree[t].v;
}
int main()
{
    int n;
    while(cin>>n){
        for( int i = 1; i <= n; i++ )
            cin>>a[i];
        flag = 0,ind = 1,ok = 0 ;
        build(1,n);
//        for( int i = 1; i <= n; i++ ){
//            printf("%d %d %d %d\n",i,tree[i].l,tree[i].r,tree[i].v);
//        }
//        puts("");
        if(flag)puts("NO");
        else {
            puts("YES");
            flag = 1;vis[0] = 1;
            post_print(1);
            puts("");
        }

    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值