C++每日一练:买苹果(两种解法)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、题目

题目描述:
小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装(包装不可拆分)。 可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。如果不能购买恰好n个苹果,小易将不会购买。

输入描述:
输入一个整数n,表示小易想购买n(1 ≤ n ≤ 100)个苹果

输出描述:
输出一个整数表示最少需要购买的袋数,如果不能买恰好n个苹果则输出-1

示例:
输入
20

输出
3

二、题目分析

看到题目的第一个想法是用集合生成,然后打表。想想还要判断所用袋子,好像不怎么靠谱。
然后想到8和6的因子是2和3,3X6=18,2X6=12,超过24的数都可以有8参与。3X8=4X6嘛。
事情就简单了!

三、代码

代码如下:

#include <string>
#include <sstream>
#include <vector>

int solution(int n){
    int result=-1;
    int bag=0;
    while(n>=0){
        if(n==0) result = bag;
        if(n>=8 && n!=18 && n!=12) n-=8, bag++;
        else n-=6, bag++;
    }
    return result;
}

int main() {

    int n;

    std::cin>>n;

    int result = solution(n);

    std::cout<<result<<std::endl;

    return 0;

总结

这题找准方向还是很容易的。这种解法肯定不是作者出题的原意,从题目来看:这肯定是为了练习动态规划用的!我这直接上了数学家的方法哈~
那也给个打表的思路,很显然测试数据很小,那么我们可以设立一个一维数组,长度为108好了,然后用一个嵌套循环生成表格:

	int vec[108]={0};
	for(int i=0; i<108; ++i) vec[i] = -1; 
    for (int i=0; i<108; i+=8){
	    for (int j=0; j<108; j+=6){
            if(i + j < 108){
	    	    vec[i+j] = i/8 + j/6;
            }else break;
        }
    }

这段代码定义了一个大小为108的整数数组,并将其所有元素初始化为0。再将所有元素设置为-1,然后,它使用两个嵌套的for循环来遍历数组中的所有元素。

在第一个for循环中,数组的所有元素都被初始化为-1。在第二个嵌套for循环中,如果一个元素与前一个元素相加后小于108,那么将其添加到数组中。如果一个元素与前一个元素相加后大于等于108,那么跳出内部循环并使用break语句终止循环。如果遍历结束时还有未访问的元素,那么使用else语句跳出内部循环。

这样做可以使代码更加清晰易懂,并且更容易维护。

最后vec[n]就取值就是了。

这里要把6循环放后面,因为放后面的先循环,后面8的循环自然会覆盖同index值的项,显然8的方案比6用的袋少。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无证的攻城狮

如本文对您有用,大爷给打个赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值