上面是题目链接。
这道题怎么做呢?
我们的思路是一个一个确定
因为我们并不能改变顺序
而且我们知道,对一个数大小影响最大的,是第一个数字
其次是第二个数字,依次往后
所以我们要尽可能是高位的数字变小
所以我们也是由高位到低位确定
如何确定呢?
我们举个例子,比如我又一个长度为10的数字,我可以删除3个数字
那么我的ans一定是长度为7的数
那么我的第一位只能在前4位当中选
因为你至少要给后面留6位
所以我们就有了一个1到4的范围,然后求出这个范围中的最小的数字,把它放入ans即可,然后继续。
我们这里解题时,ST表我们不保存我们的数字,我们保存最小数字的下标
这步操作只需要我们加一个创新的min函数即可。
代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
int m,n;
char a[1005];
char num[1005];
int f[1005][1005];
int min(int i,int j){
return a[i]<=a[j] ? i:j;
}
void ST(){
int i,j;
for(i=0;i<n;i++){
f[i][0]=i;
}
for(j=1;j<=(int)(log((double)n)/log(2.0));j++){
for(i=0;i+(1<<j)-1<n;i++){
f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
}
}
int query(int L,int R){
int x=(int)(log(double(R-L+1))/log(2.0));
return min(f[L][x],f[R-(1<<x)+1][x]);
}
int main(){
int i,j,L,R;
while(~scanf("%s%d",a,&m)){
int len=strlen(a);
n=len;
m=len-m;
ST();
i=j=0;
while(m--){
i=query(i,len-m-1);
num[j++]=a[i++];
}
for(i=0;i<j;i++){
if(num[i]!='0'){
break;
}
}
if(i==j){
printf("0\n");
continue;
}
while(i<j){
printf("%c",num[i]);
i++;
}
printf("\n");
}
return 0;
}