题目
输入样例
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");
}