小米OJ-9-移除 K 位得到最小值

描述

有一行由 N 个数字组成的数字字符串,字符串所表示的数是一正整数。移除字符串中的 K 个数字,使剩下的数字是所有可能中最小的。
假设:
字符串的长度一定大于等于 K
字符串不会以 0 开头

输入

一行由 N 个数字组成的数字字符串(0 < N < 20),和一个正整数 K(K < N),两个数据由空格隔开,如:1432219 3。

输出

移除 K 位后可能的最小的数字字符串。 如 1432219 移除 4, 3, 2 这 3 个数字后得到 1219,为所有可能中的最小值。

输入样例

1432219 3
10200 1

输出样例

1219
200


解析:这一题比较抽象,我先从移除一位入手,再推广到k位移除。判断的顺序应该是从前往后的,因为高位对于数值的影响大于低位。


在分析(10200 1)和(98100 1)输入样例的时候,在移除一位的情况下,判断当前的位是否需要移除只与后一位数有关,与后面其他的位数无关,若前一位与后一位为逆序关系,则需要移除。因为若在逆序关系中不移除当前位,则不管怎么移除之后的位,得到的数都不会成为最小值。
那么推广到k位,则需要从前往后寻找相邻逆序关系,若逆序关系个数大于等于k,则移除前k个逆序关系中的大数。若逆序关系个数不足,则要从末尾开始依次删除(因为此时数列已经有序,且递增)。
代码如下:

#include
using namespace std;

int main()
{
    string input;
    while(getline(cin,input))
    {
        istringstream ss(input);
        //删除字符串的个数
        int mnum = 0;
        string item;
        //str存放数字字符串,因为需要在中间进行删除操作,所以选择了string
        string str;
        getline(ss,str,' ');
        getline(ss,item,' ');
        mnum = stoi(item);
        for(int i = 0; i < str.size() && mnum != 0;)
        {
            //判断逆序
            if( str[i] > str[i+1] )
            {
                str.erase(i,1);                             //删除从it位置(下标)开始的第一个字符,string的专属erase()
                mnum--;
                i--;                                        //注意:删除大数后要把小数与前一个数进行逆序判断
            }
            else
            {
                i++;
            }
        }
        if(mnum != 0)
        {
            str.erase(str.size()-mnum,mnum);
            cout<

你可能感兴趣的:(小米OJ-9-移除 K 位得到最小值)