删数问题
题目描述
键盘输入一个高精度的正整数 NNN(不超过 250250250 位),去掉其中任意 kkk 个数字后剩下的数字按原左右次序将组成一个新的非负整数。编程对给定的 NNN 和 kkk,寻找一种方案使得剩下的数字组成的新数最小。
输入格式
输入两行正整数。
第一行输入一个高精度的正整数 nnn。
第二行输入一个正整数 kkk,表示需要删除的数字个数。
输出格式
输出一个整数,最后剩下的最小数。
样例 #1
样例输入 #1
175438
4
样例输出 #1
13
解题思路
这道题我一开始想的是可不可以排序,把最大的几个数给删掉,后来发现不行,因为题目要求左右次序得不变,例如,考虑141519 2
这个输入,如果直接删掉两个最大的得到是1411
,实际上最小的应该是1119
,应该删掉 4 和 5,实际上,可以发现被删的数都是一个山峰,而我们要做的就是把后面比这个山峰小的数移到前面来,也就是我们需要删掉 s[i]≥s[i+1]s[i] \geq s[i+1]s[i]≥s[i+1],需要注意的是最后前导0的处理,例如:00000123,应该输出123
代码
#include<iostream>
#include<string>
using namespace std;int main()
{string s;cin >> s;int k;cin >> k;int len = s.length();int a = len, b = k;// 保护初始值,最后需要输出 a-b个字符s = " " + s;while(k--){for(int i=1;i<len;i++){if(s[i]>s[i+1])//若出现山峰{for(int j=i;j<len;j++)//后面的字符往前移{s[j] = s[j+1];}len--;break;}}}int i = 1;while(i<=len&&s[i]=='0') i++,b++;//对前导0的处理,这里的b++相当于把0删掉了if(i==len+1) cout << 0;//0000000 最后输出0else {for(int j=i, cnt=0;cnt<a-b;cnt++,j++) cout << s[j];}return 0;
}