题目:
键盘输入一个高精度的正整数 N(不超过 250 位),去掉其中任意 k 个数字后剩下的数字按原左右次序将组成一个新的非负整数。编程对给定的 N 和k,寻找一种方案使得剩下的数字组成的新数最小。
大致思路:
贪心。删数操作结束后的最终结果的第一位取决于那些位?很简单,取决于前k+1位,前k+1位中必有以为是最后结果数字的首位,而我们要使数字更小,就要让高位越小,所以我们可以从前k+1个数中选出最小的数作为结果的首位。
假设找出的这个数字的位置为st,则为了使st变成首位,包括st在内st之前的数字要全部删除。
重复这一操作len-k次,即可。
注意处理0!!!警钟敲烂。
#include<iostream>
#include<string>
using namespace std;
string num;
int a[251];
int k,cnt=0,st=1;
bool flag=false;
int main()
{
cin>>num>>k;
int len=num.length();
for(int i=1;i<=len;++i)a[i]=num[i-1]-'0';
int rest=len-k;
while(cnt<rest)
{
int minp=st;
for(int i=st;i<=k+st;++i) if(a[minp]>a[i]) minp=i;
//寻找前k+1个位置中的最小数的位置
if(a[minp]) flag=true;
if(flag) cout<<a[minp];
k-=minp-st;
/*
由于只在前k+1个数找最小数,所以每一次删除最多也就删除k个数字
删除k个后,17行的for循环不再进行
这样就不会导致删除操作删除的数的总个数超过k
*/
st=minp+1;//下一次选数开始的位置
cnt++;
}
if(!flag)cout<<0;
return 0;
}
注意:
if(a[minp]) flag=true;
if(flag) cout<<a[minp];
这里完美做到了首位0不输出,直到出现非0数才开始输出。
附加几个测试数据:
输入:68129545206 6
输出:12206
输入:50074897 2
输出:4897
思路来源:洛谷 expin大佬