内容:
键盘输入一个高精度的正整数n(≤240位),去掉其中任意s个数字后剩下的数字按原左右次序将组成一个新的正整数。编程对给定的n和s,寻找一种方案,使得剩下的数字组成的新数最小。
输入说明:
n
s
输出说明:
最后剩下的最小数
输入样例:
键盘输入一个高精度的正整数n(≤240位),去掉其中任意s个数字后剩下的数字按原左右次序将组成一个新的正整数。编程对给定的n和s,寻找一种方案,使得剩下的数字组成的新数最小。
输入说明:
n
s
输出说明:
最后剩下的最小数
输入样例:
178543
4
输出样例 :13
这道题的思路是:一开始判断前s+1位数字,找到其中的最小值,因为如果位数都相同的话,最高位最小则数最小,删除第一个出现的最小值前面的所有数(假设有s1个)。接下来的任务就是在剩下的数组中删除s-s1个数,使得剩下的子数组满足题意,so,递归。
/**
* 一开始判断前s+1位数字,找到其中的最小值,
* 因为如果位数都相同的话,最高位最小则数最小,
* 删除第一个出现的最小值前面的所有数(假设有s1个)。
* 接下来的任务就是在剩下的数组中删除s-s1个数,使得剩下的子数组满足题意,so,递归。
*/
#include <iostream>
#include <stdio.h>
using namespace std;
void deleteNum(int* arr, int beg, int s, int n);
int main()
{
int arr[240 + 5];
int n = 0, s;
// 先把数组中所有数置位-1
for (int i = 0; i < 245; ++i) arr[i] = -1;
// 读取数组,获得n的大小,s的大小
char c;
for (int i = 0;; ++i) {
c = getchar();
if (c == '\n') break;
arr[i] = c - '0';
++n;
}
cin >> s;
deleteNum(arr, 0, s, n);
// zero是用来判断一开始的0不输出的
int zero = 0, num = 0;
for (int i = 0; num != n - s; ++i) {
if (-1 == arr[i])
continue;
if (zero == 0 && 0 == arr[i]) {
++num;
continue;
}
zero = 1;
cout << arr[i];
++num;
}
return 0;
}
void deleteNum(int* arr, int beg, int s, int n) {
if (s == 0) return;
// 剩下的位数不足s位,则这些元素不用管
// 因为我们只输出n-s位
if (beg + s >= n) return;
int min = 9;
// 找到前s+1位中最小值
for (int i = 0; i < s + 1; ++i) {
if (arr[beg + i] < min) {
min = arr[beg + i];
}
}
// 删除第一个最小值前的元素
while (arr[beg] != min) {
arr[beg] = -1;
++beg;
--s;
}
// 尾递归
deleteNum(arr, beg + 1, s, n);
}