【51nod 2491】【贪心】【单调栈】移掉K位数字

移掉K位数字

51nod 2491 移掉K位数字


题目

在这里插入图片描述
输入样例

7
1432219
3

输出样例

1219

解题思路

可以发现越小的数在前面最后得到的数就越大
所以可以贪心,一直选更小的数在前面,最后得到一个递增序列
O(N ^ 2) 用单调栈优化

特殊处理
递增序列不够长:在做单调栈的时候用一个变量标记删了几个数,删够了就直接退出
前导零:这个很容易标记,注意略去前导零并不算删掉了数,不用补数
零:会出现最后只剩零的情况,会被上一步全部略去,特判输出0


Code

#include <bits/stdc++.h>
#define N 10002

using namespace std;

int n, m, top, shan, a[N + 100], v[N + 100], q[N + 100];

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) {
		char c = getchar();
		while(!(c >= '0' && c <= '9')) c = getchar();
		a[i] = c - '0';
	}
	scanf("%d", &m);
	for(int i = 1; i <= n; i ++) {
		while(top && a[q[top]] > a[i] && shan < m) top --, shan ++;  //递增序列
		q[++ top] = i;
		if(shan == m) break;  //删的数够了直接退出
	}
	for(int i = q[top] + 1; i <= n; i ++) q[++ top] = i;  //删够了但是后面该进栈的还没进
	for(int i = 1; i <= top; i ++) v[q[i]] = 1;   //标记留下的数
	while(shan < m)  //删的不够,就从后面往前删,因为前面更小留下来更优
		v[q[top]] = 0, top --, shan ++;
	int flag = 0;
	for(int i = 1; i <= n; i ++) {
		if(v[i] && a[i] > 0) flag = 1;  //标记前导零
		if(v[i] && flag) printf("%d", a[i]);
	}
	if(!flag) printf("0");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值