C++每日一练:详解-买铅笔&影分身&三而竭

这篇具有很好参考价值的文章主要介绍了C++每日一练:详解-买铅笔&影分身&三而竭。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

这回又换成C++了,Python要用C++也要用,没有哪个正经程序员只会一门语言的,咱可是CSDN认证带V的全栈攻城狮。今天的题目除了买铅笔都还是有点难度的,虽然影分身主要是考验阅读理解能力。
C++每日一练:详解-买铅笔&影分身&三而竭


提示:以下是本篇文章正文内容,下面案例可供参考

一、买铅笔

题目描述
P老师需要去商店买n支铅笔作为小朋友们参加编程比赛的礼物。她发现商店一共有 3 种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平起 见,P老师决定只买同一种包装的铅笔。 商店不允许将铅笔的包装拆开,因此P老师可能需要购买超过 n 支铅笔才够给小朋 友们发礼物。 现在P老师想知道,在商店每种包装的数量都足够的情况下,要买够至少 n 支铅笔最少需要花费多少钱。

输入描述:
第一行包含一个正整数 n ,表示需要的铅笔数量。 接下来三行,每行用 2 个正整数描述一种包装的铅笔:其中第 1 个整数表示这种 包装内铅笔的数量,第 2 个整数表示这种包装的价格。 保证所有的 7 个数都是不超过 10000 的正整数。

输出描述:
1 个整数,表示P老师最少需要花费的钱。

示例:输入n=57, {{2, 2}, {50, 30}, {30, 27}} 输出:54

代码如下(示例):

using namespace std;
string solution(int n, int arr[3][2]){
    string result;
    // TODO:
    int minpay = 100000;
    for (size_t i=0; i<3; ++i){
        int tmp = arr[i][0];
        while (tmp<n){
            tmp += arr[i][0];
        }
        if ((tmp/arr[i][0])*arr[i][1] < minpay) minpay=(tmp/arr[i][0])*arr[i][1];
        result = to_string(minpay);
    }
    return result;
}

笔者做的题全是在原有代码的基础上改的,虽然为这点被坑了好多回,可就是不肯改。所以这里只给出solution函数就行了。

这题还是很简单的,代码中tmp是在不拆包装的情况下会买到的铅笔数,这里用的加法,其实也可以写成乘法的。乘法要判断是否整除的情况,可以用n/arr[i][0]+bool(n%arr[i][0]),运行速度应该差距不大。代码中的minpay用来表示最少地花费,比较一下取最小值就行。 需要注意的是minpay的初始值取大点,用题目所述的10000是不行的,好像只能得40分,费了我好几分钟才想到这值取小了…

二、影分身

题目描述
已知字符串str。字符串str包含字符’x’,’y’。 如果相邻的两个字符不同,消除两个字符,优先从左边进行消除。 xyyx - > yx ->

输入描述:
输入多个字符。(1<=len<=1e5)

输出描述:
输出最后的分身

示例:输入:xyyyy 输出:yyy

代码如下(示例):
这是利用了stack栈的后入先出(LIFO)的特性来做的写法,这个办法是能满分的。具体的思路就是将要保留的字符压入栈中,再和后一个对比,如示例xyyyy:
首先,定义了输入栈out,循环i=0时,因为栈是空的,就将x压入,continue继续下一个循环。i=1循环时,out的top是x、str[i] 是y,所以栈中的x被弹出,下一个循环栈又是空的了,i=2 的y被压入,以此类摔倒…直到循环完成就得到了解,因为栈的特性,只能从顶端取出数据,所以写了一个while循环,把栈中的字符又重新组合成字符串。栈的速度是极快的,比数组都要快,而且非常简单易用!用得上的函数方法就pop、push、size、top,有一点要注意的是,它和Python的list的pop方法不一样,j=out.pop(),是取不到值的。这个方法返回的是void, top()才返回栈顶的引用。

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <stack>

using namespace std;

std::string solution(std::string str){
    std::string result;
    // TODO:
    stack<char> out;
    int l = str.length();
    for (int i=0; i<l; ++i){
        if (out.size()==0){
            out.push(str[i]);
            continue;
        }
        if (str[i] == out.top()){
            out.push(str[i]);
        }else{
            out.pop();
        }
    }
    while (out.size()){
        char j = out.top();
        result = j + result;
        out.pop();
    }
    return result;
}

这题看了好久又多次测试才明白题意,它是每次消除以后要从新开始从左到右再计算的,不是第一次计算后保留下来的就一定会保留,还要再次和后面的字母比较,所以最终的结果只会有x或y。理解这一点后,就相对比较简单了,一开始笔者写了个递归来做,测试用例是没问题的。但实际执行会提示:terminate called after throwing an instance of 'std::bad_alloc'内存分配不足了!果然递归不靠谱。这里也给出递归写法以供参考:

string reduce(string str){
    int l = str.length();
    if (l==0 || l==1){
        return str;
    } 
    for (int i=0; i<l; ++i){
        if(str[i]==str[i+1] && i+1==l-1){
            return str;
        } 
         else if(str[i]!=str[i+1] && i+1<l){
            str=str.substr(0,i)+str.substr(i+2,l);
            break;
        } 
    }
    return reduce(str);
}

这个写法相对前面的代码显得很简洁,思路也简单,退出递归的条件是三个:一是消完了,二是只剩下一个字符,三是全部字符都一样。后面就是每次递归消除二个字符。测试发现不能过关,才改成stack栈的写法,说明测试用例中有极长的字符串。

三、三而竭

这题之前做过了,难度系数在笔者看来还是有点高的,当时也费了不少时间才解出来,主要是容易超时。是一个凑数字的题,暴力凑的方法,其中几个数的取值范围很重要。笔者也没有想出其它更好的办法,按这个解法用了600多ms的时间,算是免费过关。请见:

https://blog.csdn.net/alal001/article/details/130119027


总结

希望本文能对各位看官有所启发,原创文章,未经许可,请勿转载。文章来源地址https://www.toymoban.com/news/detail-449733.html

到了这里,关于C++每日一练:详解-买铅笔&影分身&三而竭的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++每日一练(7):爬山

    题目描述 LeiQ最近参加了一个登山俱乐部,部长给他了一个n*m地图,地图上的每一个格子的值表示一个山的海拔高度,LeiQ现在在(x,y)表示在地图上的位置,他想要登上地图上最高的山,所以他想知道他爬上最高的山的山顶还需向上爬多少米。 例如:  xy 1 2 3 1 100  130  150 2 200  

    2024年02月03日
    浏览(25)
  • C++每日一练(8):图像相似度

    题目描述 给出两幅相同大小的黑白图像(用0-1矩阵)表示,求它们的相似度。 说明:若两幅图像在相同位置上的像素点颜色相同,则称它们在该位置具有相同的像素点。两幅图像的相似度定义为相同像素点数占总像素点数的百分比。 输入 第一行包含两个整数m和n,表示图像

    2024年02月03日
    浏览(35)
  • C++每日一练(15):简单幂计算

    题目描述 输入两个数a和b,求a的b次方。 输入 输入两个整数a,b(1=a=10,1=b=15)。 输出 输出一个正整数,该值=1000000000000。 输入样例 3 3 输出样例 27 参考答案 这段是用了pow函数,当然也可以用for循环实现(这里就不展示了哈)。 

    2024年01月17日
    浏览(49)
  • C++每日一练:最长递增区间 && 阿波罗的魔力宝石 && 投篮

    今天的题太简单,甚至 “最长递增区间” 和 “投篮” 就是一个问题。实在没事干,也给做了!直接上代码算了… 提示:以下是本篇文章正文内容 代码如下: 注意点就是默认值为1。 代码如下: 很简单的冒泡排序,没加flag。 代码如下: 这简直和第一题一模一样!我估计条

    2023年04月26日
    浏览(42)
  • 【每日一题Day312】LC2240买钢笔和铅笔的方案数 | 完全背包 数学

    买钢笔和铅笔的方案数【LC2240】 给你一个整数 total ,表示你拥有的总钱数。同时给你两个整数 cost1 和 cost2 ,分别表示一支钢笔和一支铅笔的价格。你可以花费你部分或者全部的钱,去买任意数目的两种笔。 请你返回购买钢笔和铅笔的 不同方案数目 。 一眼背包问题 原来数

    2024年02月10日
    浏览(39)
  • 蓝桥杯 2240. 买钢笔和铅笔的方案数c++解法

             最近才回学校。在家学习的计划不翼而飞。但是回到学校了,还是没有找回状态。         现在是大三了,之前和同学聊天,说才大三无论是干什么,考研,找工作,考公,考证书 还都是来的及的。        但是心里面有点慌 还要学习的东西太多了,离找

    2024年02月10日
    浏览(30)
  • 百题千解计划【CSDN每日一练】“小明投篮,罚球线投球可得一分”(附解析+多种实现方法:Python、Java、C、C++、C#、Go、JavaScript)

      这个心上人,还不知道在哪里,感觉明天就会出现。     🎯作者主页: 追光者♂🔥          🌸个人简介:   💖[1] 计算机专业硕士研究生💖   🌟[2] 2022年度博客之星人工智能领域TOP4🌟   🏅[3] 阿里云社区特邀专家博主🏅   🏆[4] CSDN-人工智能领域优质创作者🏆

    2024年02月15日
    浏览(50)
  • python每日一练(9)

       🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如需转载还请通知⚠️ 📝个人主页:Aileen_0v0🧸—CSDN博客 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 📣系列专栏:Ailee

    2024年02月07日
    浏览(33)
  • Python每日一练(20230430)

    目录 1. 移除元素  🌟 2. 删除排序链表中的重复元素  🌟 3. 搜索旋转排序数组 II  🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C++每日一练 专栏 Java每日一练 专栏 给你一个数组  nums   和一个值  val ,你需要 ​ 原地 ​ 移除所有数值等于 

    2024年02月02日
    浏览(29)
  • 力扣、每日一练:爬楼梯

    假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n = 2 输出:2 解释:有两种方法可以爬到楼顶。 1 阶 + 1 阶 2 阶 示例 2: 输入:n = 3 输出:3 解释:有三种方法可以爬到楼顶。 1 阶 + 1 阶

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包