![](http://acm.fzu.edu.cn/image/problem.gif)
Accept: 83 Submit: 258
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Given you one n-digital positive integer a,After removing any of them k( k < n) digits, the remaining figures form a new positive integer according to the origin order. For a given n-digital positive integers a and positive integer k. Now ask you to find a algorithm to minimize the remaining integer.
Input
The first line contains one integer t, represents the number of test cases.
Then following t lines,each line contain two numbers a,k (0 < a < 10^1000, k is less than the length of a).
Output
Output the mininum number after the deletion.(the number can not contain leading zero)">
it means that we should ignore the leading zeros of the output number
Sample Input
1178543 4
Sample Output
13
题意:
删除k个数,使得这个数最小。
思路:
这题简直坑货,让高数位尽量小,于是就要从前向后扫,每次就删当前数前面,比自己大的数;然而注意前导0不输出。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N= 1005;
char s[N];
int vis[N];
int main()
{
int t,k;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof vis);
scanf("%s%d",s,&k);
int len=strlen(s);
for(int i=1; i<len; i++)
{
for(int j=i-1; j>=0; j--)//从最近的删起
{
if(!vis[j]&&s[j]>s[i]) vis[j]=1,k--;
if(!k) break;
}
if(!k) break;//两次break;
}
if(k)
{
for(int i=len-1; i>=0; i--)
{
if(!vis[i]) vis[i]=1,k--;
if(!k) break;
}
}
int f=1;
for(int i=0; i<len; i++)
if(!vis[i])
{
if(f&&s[i]=='0') continue;
if(s[i]!='0') f=0;
putchar(s[i]);
}
if(f) printf("0");//都是0,则输出0
puts("");
}
return 0;
}
另外一种用单调栈做的。代码更简单。时间复杂度O(n)。
#include<cstdio>
const int maxn=1010;
char num[maxn],q[maxn];
int main()
{
int t,i,k,tail;
scanf("%d",&t);
while(t--)
{
scanf("%s%d",num,&k);
tail=0;
for(i=0;num[i];i++)
{
while(tail&&num[i]<q[tail-1]&&k)
tail--,k--;
q[tail++]=num[i];
}
while(k)
k--,tail--;
q[tail]=0;
for(i=0;i<tail;i++)
if(q[i]!='0')
break;
if(i==tail)
printf("0\n");
else
printf("%s\n",q+i);
}
return 0;
}