题目描述
键盘输入一个高精度的正整数 N(不超过 250 位),去掉其中任意 k 个数字后剩下的数字按原左右次序将组成一个新的非负整数。编程对给定的 N 和 k,寻找一种方案使得剩下的数字组成的新数最小。
输入格式
n(高精度的正整数 )。
k(需要删除的数字个数 )。
输出格式
最后剩下的最小数。
输入输出样例
输入 #1
175438 4
输出 #1
13
思路:
(设数字长度为len,j为现在要选数填入的位置,index为n中各个数字的位置,temp为还需要填入数的个数)
本题要删除k个数使剩下的数最小,可以按照删数的思路,也可以反过来想,保留len-k个数,这些数按原左右次序排列,组成的数最小。
所以要使组成的数最小,我们就要从高位到低位,依次填数(即j从0到len-k)。每次填数的时候要使用贪心策略,即每次都是选剩下的数里最小的数。但是!!!!,题目要求按原来的次序排列,所以对于当前位,选出来的数的位置index要大于前一个数的位置index,小于temp.
#include<cstdio>
#include<iostream>
#include<vector>
#include<iomanip>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iterator>
using namespace std;
struct Node {
int num;
int index;
};
string n;
int k;
Node s[255];
int vis[255];
bool comp(Node a, Node b) {
if (a.num == b.num)return a.index < b.index;
return a.num < b.num;
}
int main()
{
cin >> n >> k;
for (int i = 0; i < n.length(); i++) {
s[i].num = n[i] - '0';
s[i].index = i;
}
//按数的大小排序
sort(s, s + n.length(), comp);
int temp = n.length() - k;
int ans[255];
int j = 0;
int lindex = -1; //上一个数的位置
while (temp) {
for (int i = 0; i < n.length(); i++) {
if (!vis[i]&&s[i].index > lindex&& s[i].index < n.length() - temp + 1) { //没有被选过,且当前数是在可选的区间内
lindex = s[i].index;
ans[j++] = s[i].num;
vis[i] = 1;
temp--;
break;
}
}
}
int flag = 0;
for (int i = 0; i < j; i++) {
if (ans[i] != 0 || flag == 1) {
flag = 1;
cout << ans[i];
}
}
if (flag == 0)cout << "0" << endl;
return 0;
}