题目描述
给定一个十进制正整数 n (0<n<10000000000),每个数位上数字均不为 0。n 的位数为 m。
现在从 m 位中删除 k 位 (0<k<m),求生成的新整数最小为多少?
例如: n=9128456, k=2, 则生成的新整数最小为 12456。
输入
第一行 T, 表示有 T 组数据。
接下来 T 行,每一行表示一组测试数据,每组测试数据包含两个数字 n,k。
输出
T 行,每行一个数字,表示从 n 中删除 k 位后得到的最小整数。
输入输出样例
样例输入 #1
2
9128456 2
1444 3
样例输出 #1
12456
1
问题分析:碰到该题我们首先想到的是,把给的整数拆分,然后装入到数组中。在该题中,我们需要从左往右扫描,如果出现了降序也就是第i个数大于第i+1个数,此时我们就可以删掉第i个数(类似于题目:排列(POJ 1833))。这样在我们删掉k个数后,我们就得到了最小新整数。 但是在拆分时使用“%”和“/”取位数是十分麻烦的,于是我们可以采用c++内置的string类型,这样不管是求给定数的长度还是存数都是十分方便的,大大减少了我们编写代码的时间复杂度和空间复杂度。
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 1000;
int arr[MAXN],T,k,l;
string n; //输入改为字符串
int main() {
cin >> T;
while (T--) {
memset(arr, 0, sizeof(arr));
cin >> n >> k;
l = n.length(); //给定数的长度
for (int i = 0; i < l; i++) arr[i] = n[i] - '0'; //将字符变成整形存入数组arr中
while (k--) { //删除k个数
for(int i=0;i<l-1;i++)
if (arr[i + 1] < arr[i]) {
for (int j = i; j < l - 1; j++) arr[j] = arr[j + 1]; //可联想插入排序
break;
}
l--; //没删除一个数原本的长度都会减少
}
for (int i = 0; i < l; i++) cout << arr[i];
cout << endl;
}
return 0;
}