51nod 2491贪心单调栈移掉K位数字
Posted SSL_ZZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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");
以上是关于51nod 2491贪心单调栈移掉K位数字的主要内容,如果未能解决你的问题,请参考以下文章