中石油:http://exam.upc.edu.cn/problem.php?id=4509
【问题】:
给出一个n位数,要求删掉其中k位数字,使得剩下的数字组成的数尽量大。
输入
第1行:两个正整数n, k(1 <= k < n <= 500,000)。
第2行:一个n位正整数(无前导0)。
第2行:一个n位正整数(无前导0)。
输出
输出一行,一个正整数,表示剩下的数的最大值。
样例输入
4 2
1924
样例输出
94
【解析】:
目的是使得高位尽量大。
贪心
因此,从左边开始扫,设两个下标,l和r
r一直往右走。
l始终在r的左边
只要a[l]<a[r],就把l删掉,因为保留a[r]会更好
否则,r++,l从r的左边重新执行这个过程
这个过程执行完,一定会剩下一个不上升的序列,需要继续删的话,从右边开始删小数。
【代码】:
#include <stdio.h>
#include <string.h>
#include <iostream>
#define mset(a,i) memset(a,i,sizeof(a))
using namespace std;
typedef long long ll;
const int MAX=1e6+5;
char a[MAX];
int vis[MAX];
int main()
{
int n,k,i,j;
while(cin>>n>>k)
{
scanf("%s",a);
int l=0,r=1;
mset(vis,0);
while(k&&r<n)//删升的
{
while(k&&l>=0&&a[l]<a[r])
{
vis[l]=1;
k--;
while(l>=0&&vis[l])l--;
}
l=r;r++;
}
r=n-1;
while(k&&r>=0){//扫描剩下的不升序列
if(!vis[r]){
vis[r]=1;
k--;
}
r--;
}
int flag=1;
for(int i=0;i<n;i++)
{
if(!vis[i]){
flag=0;
printf("%c",a[i]);
}
}
if(flag)printf("0");
puts("");
}
return 0;
}