CPP-SCNUOJ-Problem P15. [算法课贪婪]移掉 K 位数字【小白都懂,第三刷方法最简洁】

Problem P15. [算法课贪婪]移掉 K 位数字
给你一个以字符串表示的非负整数 num 和一个整数 k ,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
1 <= k <= num.length <= 1000
num 仅由若干位数字(0 - 9)组成
除了 0 本身之外,num 不含任何前导零
输入
输入一串字符串表示非负整数和一个整数k。字符串和k之间空格隔开。
输出
输出一串字符串表示结果。

样例

标准输入 复制文本

432219 3

输出 复制文本

1219

标准输入 复制文本

10200 1

标准输出 复制文本

200

标准输入 复制文本

10 2

标准输出 复制文本

0

思路:要保证数字的递增的,不是递增的,就把那一位去掉,去掉的方法用字符串连接来处理;如果全都是递增的,那就去掉后面的几位;最后,前面有0的,就去掉0.

#include <iostream>

using namespace std;

string sub(string s, int left, int right)//截取字符串,开始,停止,right这位是不取的
{
    string temp = "";
    for(int i=left; i<right; i++)
    {
        temp += s[i];
    }
    return temp;
}
int main()
{
    string s;//输入的字符串
    int k;//移除k位数字
    cin >> s;
//    cout << sub(s,1,3);

    cin >> k;
    //如果去除的k位>=字符串长度,则输出0
    if(k >= s.length())
    {
        cout << 0;
        return 0;
    }
    for(int i=0; i<k; i++)
    {
        bool flag = 1;//如果数列是递增的,则除去后面的k位
        for(int j=0; j<s.length()-1; j++)
        {
            if(s[j] > s[j+1])
            {
                s = sub(s,0,j)+sub(s,j+1,s.length());
                flag = 0;
                break;
            }
        }
        if(flag)
        {
            s = sub(s,0,s.length()-1);
        }
    }
    //当前面都是0,则去掉0
    while(s[0]=='0' && s.length()>1)
    {
        s = sub(s,1,s.length());
    }

    cout << s;
//    cout << "Hello world!" << endl;
    return 0;
}

自我练习二刷

#include <iostream>

using namespace std;

//截取字符串
string sub(string s, int left, int right)
{
    string t = "";
    for(int i=left; i<right; i++)
    {
        t += s[i];
    }
    return t;
}

int main()
{
    string s;
    int k;// 移除k位数字
    cin >> s;
    cin >> k;
    // 移除k位数字,大于字符串长度,直接移没了
    if(k >= s.length())
    {
        cout << 0;
        return 0;
    }
    // 要移除k位数字,进行k次循环,一次循环移除一位
    for(int i=0; i<k; i++)
    {
        bool flag = 1;//如果数列是递增的,flag=1,则只需要移除最后面的k位数字
        //这里的s.length()会变化,因为会移除,所以不宜在前面直接取int len;
        for(int j=0; j<s.length()-1; j++)//前后两位比价大小,用到j+1,所以截止条件是len-1;前面的大,就移除前面的
        {
            if(s[j] > s[j+1])
            {
                s = sub(s,0,j) + sub(s,j+1,s.length());
                flag = 0; //说明数列不是递增的
                break;//结束这一层for循环,回到最外层,再继续移除数字,直到移除k位数字;
            }
        }
        if(flag)//如果数列递增
        {
            s = sub(s,0,s.length()-1);//因为要进行k层循环,每次移除一个数字,所以这里只需要s.length()-1;
        }
    }
    //当前面都是0,则去掉0;
    while(s[0] == '0' && s.length()>1)
    {
        s = sub(s,1,s.length());//去掉一个0,还有的话,继续循环再次去掉;
    }
    cout << s;
//    cout << "Hello world!" << endl;
    return 0;
}

三刷,自己琢磨出来的,网上还好像没有搜到字符串数组的这种用法,牛逼死我了哈哈哈哈哈

参考文章vector删除元素用法

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
/*
思路:要满足数字串是递增;
    移除k位数字,即进行k次循环
    不是递增,就把当前位置的数字去掉,用字符串连接的方法来去掉
    是递增,则去除最后一个即可
*/
int main()
{
    string s;
    int k;
    cin >> s >> k;

//    cout << s << endl;
//    cout << k << endl;
//
//    cout << s[2] << endl;
//    cout << s.back() << endl;
//    s.pop_back();
//    cout << s << endl;
//    s.erase(s.begin()+2);
//    cout << s << endl;
//    s.erase(s.begin());
//    cout << s << endl;

    if(k >= s.length())
    {
        cout << 0;
        return 0;
    }
    for(int i=0; i<k; i++)
    {
        bool flag = 1;
        for(int j=0; j<s.length()-1; j++)
        {
            if(s[j] > s[j+1])
            {
                s.erase(s.begin()+j);
                flag = 0;
                break;
            }
        }
        if(flag)
        {
            s.pop_back();
        }
    }
    while(s[0] == '0' && s.length()>1)
    {
        s.erase(s.begin());
    }
    cout << s;
//    cout << "Hello world!" << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值