看了下网上的解法觉得自己的更好一点,与大家分享
下面是题目:
给定一个十进制的正整数number,选择从里面去掉一部分数字,希望保留下来的数字组成的正整数最大。
输入描述:
输入为两行内容,第一行是正整数number,1 ≤ length(number) ≤ 50000。
第二行是希望去掉的数字数量cnt 1 ≤ cnt < length(number)。
输出描述:
输出保留下来的结果。
示例1
输入
325 1
输出
35
/*
自己的看法,希望大家批评指正
其实我觉得测试用例没有问题
题目明确了输入数组的长度在50000量级
因此选择使用string来表示
我做这道题的思路: 题目说删除给定数字的规定个数使之最大
我们就假设这个数 n 位,要删除 b 个元素,使剩下的 n - b个元素组成最大
另外一个数值的大小取决于它的首位
因为不能改变每个数字的位置,所以其实我们只能在前 b 个元素里选出最大的
作为首位(你只能最多删除 b 个元素,即使 b+1个元素比之前都大
你也没办法把它变成首位)
基于这种思想,b 的大小就是你遍历首位元素(最大元素)的半径
找到前 b 个元素的最大值 max,把 max作为首位,并删除 max之前的元素
这样一来,我们就找到了结果的第一位元素
接下来只要把 b 的值更新(b = b - 之前删掉的元素个数)
也要把这个数更新(删去它最大值后的子序列(不包含最大值))
这样我们就回到了与上面类似的情况,同样的用此时的半径 b (比刚才小)
去找出最大元作为此时的首位(其实是结果的第二位)再更新 b 值和数字序列
直到最后满足条件退出
下面是我的 AC代码
*/
#include<iostream>
#include<string.h>
#include<vector>
using namespace std;
string fun(string a,int b)
{
string res="";
int len = a.length()-b; //删除 b个,其实就是要填满剩下的 n-b个
//我们用上面的方法一个一个填进去
while(len!=0) //len表示要填的长度,填满了退出
{
char max = 0;
// 找到前 b个中的最大值
for(int i=0;i<=b;i++)
{
if(max<a[i])
max = a[i];
}
int index = a.find_first_of(max);
b = b - index; //更新 b 值
res = res + max; //string类型的res存储结果
len--; //填一个格子少一个
// 将首位元素之前的删除,也就是更新原来的数字序列
a = a.substr(index+1);
//这是当半径为 0 表示没有再搜索下去的能力了,此时就把后面的元素直接加上
if(b==0)
{
res = res+a;
break;
}
}
return res;
}
int main()
{
string a;
int b;
while(cin >> a >> b)
{
cout << fun(a,b) << endl;
}
return 0;
}