寒假刷题第八天

PTA甲级

1043 Is It a Binary Search Tree


若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值
若它的右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值
它的左、右子树也分别为二叉搜索树
二叉搜索树的中序遍历是一个有序的序列
此题就变为已知中序遍历和前序遍历 建树
最为重要的一点就是题目没有保证元素不重复
原BST树取所有相同值的第一个
镜像BST树取所有相同值的最后一个

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

const int N = 1010;
int n;
int pre[N] , in[N];
vector<int>post;

bool build(int pl , int pr , int il , int ir , int type)
{
    if(il > ir) return true;
    int k = pre[pl];
    int j;
    if(!type) 
    {
        j = il;
        while(j <= ir && in[j] != k) j ++;
        if(j > ir) return false;
    }
    else
    {
        // 右子树
        j = ir;
        while(j >= il && in[j] != k) j --;
        if(j < il) return false;
    }
    if(!build(pl + 1 , j - il + pl , il , j - 1 , type)) return false;
    if(!build(pr - ir + j + 1 , pr , j + 1 , ir , type)) return false;
    post.push_back(k);
    return true;
}

int main()
{
    cin >> n;
    for(int i = 0;i < n;i ++) cin >> pre[i] , in[i] = pre[i];
    sort(in , in + n);

    bool f = build(0 , n - 1 , 0 , n - 1 , 0);
    if(f) puts("YES");
    else
    {
        post.clear();
        reverse(in , in + n);
        f = build(0 , n - 1 , 0 , n - 1 , 1);
        if(f) puts("YES");
        else puts("NO");
    }
    if(f) 
    {
        for(int i = 0;i < post.size();i ++)
        {
            if(i) cout << " ";
            cout << post[i];
        }
    }
    return 0;
}

1044 Shopping in Mars

双指针算法

//可以使用双指针法解决问题
#include<iostream>
#include<vector>

using namespace std;
const int N = 1e5 + 10;
int n,m;
vector<int>v(N);
vector< pair<int,int> >res;
int min_num = 0x3f3f3f3f;
void cal_qu()
{
    int sum = 0;
    //i向右移移动sum值变小
    //j向右移动sum值变大
    for(int i = 0,j = 0 , sum = 0;j < n || sum >= m;)
    {
        if(sum > m)//在i到j的区间内的和大于给定的值
        {
            min_num = min(sum,min_num);
            //更新sum并且将i指针向右移动
            sum -= v[i++]; 
        }
        else if(sum < m)//在i到j的区间内的和小于给定的值
        {
            //更新sum并且将j指针向右移动
            sum += v[j++];
        }
        else//在i到j的区间内的和等于给定的值
        {
            //存入结果中
            //注意起始坐标是从1开始的
            res.push_back({i+1,j});
            //更新sum并且将i指针向右移动
            sum -= v[i++];
        }
    }
}

void print()
{
    for(int i=0;i<res.size();i++)
    {
        cout<<res[i].first<<"-"<<res[i].second<<endl;
    }
}

int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++) cin>>v[i];
    
    cal_qu();
    print();
    
    if(!res.size())
    {//表示没有一个结果等于原先的m
     //更新m重新进行计算
        m = min_num;
        cal_qu();
        print();
    }
}

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值