题目表述:
就是给你一个数字(不超过250位),再给你数字K,数字k表示,你必须得删除掉这个数字中的K位,使得这串数字最小,求最小的结果;
题目分析:
我们先来想想,一个数字,在上面情况下尽可能小呢?显然,只有这个数字的每一位都呈现出单调上升(不严格)才会变得更小
法一:纯模拟,枚举每一位,以及被删除掉的数字的个数,O(N^2*K)代码双手奉上:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=240+5;
char a[N];
int s;
int main()
{
while (scanf("%s%d",a,&s)!=EOF)
{
bool flag=false;
int len=strlen(a);
for (int i=1;i<=s;i++)
{
for (int j=0;j<=len-1;j++)
{
if (a[j]>a[j+1])
{
for (int k=j;k<=len-1;k++)
a[k]=a[k+1];
break;
}
}
len--;
}
for (int i=0;i<=len-1;i++)
{
if (a[i]!='0'||i==len-1)
flag=1;
if (flag)
printf("%c",a[i]);
}
printf("\n");
}
return 0;
}
法二:可以用单调栈,使得每一个元素只会进栈一次,时间复杂度:O(N*STL复杂度)
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2.4e2+5;
char c[N];
int s;
int main()
{
while(~scanf("%s\n%d", c, &s))
{
int len=strlen(c), tmp=s;
while(s)
{
int wz=strlen(c)-1;
bool flag=true;
for(int i=0; i<len-1; ++i)
{
if(c[i]>c[i+1])
{
flag=false;
wz=i;
break;
}
}
if(!flag)
{
for(int i=wz; i<len-1; ++i)
c[i]=c[i+1];
}
--s;
}
int first=0, last=len-tmp-1;
for(int i=0; i<len-tmp; ++i)
{
if(c[first]=='0' && first!=last)
{
++first;
continue;
}
else cout<<c[i];
}
putchar(10);
}
return 0;
}