删数游戏(单调栈)

P1106 删数问题

题意:删去k个数字,使剩下的数字最小。

题解:我们考虑两个数字,肯定高位低的数字更小,随后再尽量保证低位小。

利用单调栈维护一个n-k长的上升序列,如果新入栈的数比栈顶小就一直出栈直到不小。

因为序列要保证长度,每个数只会入栈一次,出栈就删一个数。不过很有可能没删完就结束了。

所以循环结束,需要把n-k以上的删完。特判下0。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<stack>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;

#define M 500050
#define Color 500050

int K;
stack<int>t;
int x;
int A[M];
string st;

int main(){
    cin>>st>>K;
    int k=K;
    FOR(i,1,st.size()){
        x=st[i-1]-'0';
        while(!t.empty()&&k&&x<t.top())t.pop(),k--;
        t.push(x);
    }
    while(k&&!t.empty())k--,t.pop();
    int cnt=st.size()-K;
    while(!t.empty()){
        A[cnt--]=t.top();
        t.pop();
    }
    int s=1;
    while(A[s]==0&&s<st.size()-K)s++;
    FOR(i,s,st.size()-K)printf("%d",A[i]);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值