PAT 1101. Quick Sort (25)

题意:给你一个长度为n的数组,问你有几个数满足左边的都比它小,右边的都比它大,并输出他们。

思路:自从11月退役后好久好久没做题了。。不会做题了,,这么水的题,只要找到每个数左边的最大值和右边的最小值跟自己比较一下就行了,我上来居然想到用线段树、、、、其实从头和从尾巴扫一遍记录下最值就可以了。。。


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
int a[maxn], n;
int okL[maxn], okR[maxn];
int res[maxn];

int main(void)
{
    while(cin >> n)
    {
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        memset(okL, 0, sizeof(okL));
        memset(okR, 0, sizeof(okR));
        int tmp = -INF;
        for(int i = 1; i <= n; i++)
        {
            if(a[i] < tmp) okL[i] = 1;
            tmp = max(tmp, a[i]);
        }
        tmp = INF;
        for(int i = n; i >= 1; i--)
        {
            if(a[i] > tmp) okR[i] = 1;
            tmp = min(tmp, a[i]);
        }
        int ans = 0;
        for(int i = 1; i <= n; i++)
            if(!okL[i] && !okR[i])
                res[ans++] = a[i];
        printf("%d\n", ans);
        for(int i = 0; i < ans; i++)
            printf("%d%c", res[i], i==ans-1 ? '\n' : ' ');
        if(!ans) puts("");
    }
    return 0;
}

好久没写线段树了,,就当复习线段树。。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e5+5;
int n;
int a[maxn], A[maxn], Hash[maxn];
int treeMax[maxn*4], treeMin[maxn*4];

void build(int root, int l, int r)
{
    if(l == r)
    {
        treeMax[root] = treeMin[root] = A[l];
        return ;
    }
    int mid = (l+r)/2;
    build(root*2, l, mid);
    build(root*2+1, mid+1, r);
    treeMax[root] = max(treeMax[root*2], treeMax[root*2+1]);
    treeMin[root] = min(treeMin[root*2], treeMin[root*2+1]);
}

int queryMax(int root, int l, int r, int i, int j)
{
    if(i <= l && j >= r)
        return treeMax[root];
    int mid = (l+r)/2;
    int ans = -1;
    if(i <= mid) ans = max(ans, queryMax(root*2, l, mid, i, j));
    if(j > mid) ans = max(ans, queryMax(root*2+1, mid+1, r, i, j));
    return ans;
}

int queryMin(int root, int l, int r, int i, int j)
{
    if(i <= l && j >= r)
        return treeMin[root];
    int mid = (l+r)/2;
    int ans = maxn+1;
    if(i <= mid) ans = min(ans, queryMin(root*2, l, mid, i, j));
    if(j > mid) ans = min(ans, queryMin(root*2+1, mid+1, r, i, j));
    return ans;
}

int res[maxn];

int main(void)
{
    while(cin >> n)
    {
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]), Hash[i] = a[i];
        sort(Hash+1, Hash+1+n);
        int d = unique(Hash+1, Hash+1+n)-Hash-1;
        for(int i = 1; i <= n; i++)
            A[i] = lower_bound(Hash+1, Hash+1+d, a[i])-Hash;
        build(1, 1, n);
        int tmp, ans = 0;
        for(int i = 1; i <= n; i++)
        {
            if(i == 1)
            {
                tmp = queryMin(1, 1, n, 2, n);
                if(tmp > A[i])
                    res[ans++] = a[i];
            }
            else if(i == n)
            {
                tmp = queryMax(1, 1, n, 1, n-1);
                if(tmp < A[i])
                    res[ans++] = a[i];
            }
            else
            {
                int R = queryMin(1, 1, n, i+1, n);
                int L = queryMax(1, 1, n, 1, i-1);
                if(L < A[i] && R > A[i])
                    res[ans++] = a[i];
            }
        }
        printf("%d\n", ans);
        for(int i = 0; i < ans; i++)
            printf("%d%c", res[i], i==ans-1 ? '\n' : ' ');
        if(ans == 0) puts("");
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值