前两天打了2021年度训练联盟热身训练赛第一场

这个e题还是蛮不错的

链接:https://ac.nowcoder.com/acm/contest/12606/E

样例输入

链接:https://ac.nowcoder.com/acm/contest/12606/E
来源:牛客网

示例1
输入
6 3
3
2
1
3
1
3

输出
2 1 3

示例2
输入
10 5
5
4
3
2
1
4
1
1
5
5

输出
3 2 1 4 5

题意大概是:给出一段数字序列,要求按照顺序取元素组成子列,子列有1-k的数字,并且子列值最小

这道题可以用栈来解决:先把第一个元素压入栈,然后接下来判断栈顶元素是否大于当前元素值,是的话就弹出(前提是后面还存在这个元素,以便于它可以再次被压进来)

如果当前元素以及在栈里面,那么上述规则不生效(防止同一多次压进去)

最后,代码是这样子的:

#include<bits/stdc++.h>
using namespace std;

#define MAXN 200005
int x[MAXN] = { 0 };
int js[MAXN] = { 0 };
bool in_stack[MAXN] = { false };

int main()
{
    int k, n;
    scanf("%d%d", &n, &k);

    for (int i = 0; i < n; ++i)
    {
        scanf("%d", &x[i]);
        js[x[i]]++;
    }

    stack<int> s;
    s.push(x[0]);
    js[x[0]]--;
    in_stack[x[0]] = true;

    for (int i = 1; i < n; ++i)
    {
        js[x[i]]--;
        //if(x[i]==1) cout<<"aaa"<<in_stack[1]<<endl;
        while (!s.empty() && (s.top() > x[i]) && (js[s.top()] > 0) && in_stack[x[i]] == false)
        {
            in_stack[s.top()] = false;
            s.pop();
        }
        if (in_stack[x[i]] == false)
        {
            s.push(x[i]);
            in_stack[x[i]] = true;
            //cout<<x[i]<<' '<<in_stack[x[i]]<<endl;
        }

    }
    list<int> li;

    while (!s.empty())
    {
        li.push_front(s.top());
        s.pop();
    }

    while (!li.empty())
    {
        printf("%d", li.front());

        if (li.size() > 1)
            printf(" ");
        else printf("\n");


        li.pop_front();
    }
    //system("pause");
}

转载请注明来源:https://www.longjin666.top/?p=813

你也可能喜欢

发表评论