【C++】 —— 笔试刷题day_11

一、游游的水果大礼包

题目解析

现在有n个苹果、m个桃子,我们现在可以将2个苹果和1个桃子组成一号大礼包1个苹果和2个桃子组成二号大礼包

一号大礼包 的价值为a二号大礼包 的价值为b

要我们求出来,我们可以组合出来的礼包的最大价值。

算法思路

本道题,正确的解法是枚举

题目给了n个苹果,m个桃子;

那我们就枚举出来所有的情况(组合一号礼包0个到组合一号礼包最多个 ),这样我们一号礼包的个数的区间为 [0 , x]

那这个x怎么去求呢?(这算是本道题第一个坑 ,博主在第一次做时就将max求错了导致这道题没有通过)(先继续往下看)

在我们枚举一号礼包二号礼包的数量时,我们要求的价值就等于count1*a + count2*b

在遍历的过程中,更新结果即可。

现在来看这里比较重要的点

  • 一号礼包个数区间[0 , x]中的x如何去求? :这里我们不仅要考虑苹果是数量n,也要考虑桃子的数量m;那max就应该等于苹果能组成一号礼包的数量n/2和桃子能够组成一号礼包的数量m的最小值,x = min(n/2 , m)
  • 还用一个要注意的点,就是数据的范围 ,题目中给定n,m,a,b的范围是[1 , 1000000];那这样我们最终结果使用int肯定是不行的,要使用long long类型。

这里,如果想要使用贪心算法进行优化是行不通的,题目中给的条件太少了,这里就不讲解使用贪心优化了。

代码实现

cpp 复制代码
#include<iostream>
using namespace std;

int main()
{
    int n,m,a,b;
    cin>>n>>m>>a>>b;
    int t = min(n/2,m);
    long long ret = 0;
    for(int x = 0;x<=t;x++)
    {
        long long y = min(n - 2*x,(m - x)/2);
        ret = max(ret , x*a + y*b);
    }
    cout<<ret<<endl;

    return 0;
}

二、买卖股票的最好时机(二)

题目解析

昨天的是买卖股票的最好时机(一),现在(二)来了。

现在来看题,还是给定一个数组paices,表示每一天股票的价格,我们现在要根据这个价格表paices返回买卖股票的最大利益

和上道题目不同的是

  • 我们可以多次买卖股票,但是再次购买股票之前,必须卖出之前的股票(简单来说就是,我们手中最多只能存在一种股票
  • 如果没有收益,就返回0
  • 买卖股票没有手续费(就是没有损耗)

算法思路

这道题,算法思路就是贪心(那我没有学过贪心怎么办?不要慌,博主也只是听说过贪心而已)

现在来看整体思路:

在这道题中,我们可以多次买卖股票,所以我们不管三七二十一,直接买入股票,如果后面股票价格要高于我们买入的价格,那就卖出赚取利润;如果不高于我们买入的价格,那就当天买当天卖嘛,反正有没有亏损。

其实整道题的思路就是上述买卖股票的方法,那转化成我们代码,该如何理解呢?

  • 从左往右遍历数组paices表示我们买卖股票的整个过程
  • 遍历到i位置时,就表示在第i天买入股票
  • 我们定义j,让ji+1位置开始向后遍历,如果paices[j] <= paices[j-1](就表示卖出的价格不高于买入的价格/股票在降价 ,那我们就要早点卖出了,就当天买当天卖,没有利润 );如果paices[j] > paices[j-1](就表示当前股票价格在上涨,我们先不买,找到股票的最高价格再卖出)。
  • j遍历结束后,将j的值赋给i,让ij位置再遍历数组paices

整体思路如上,我们现在来梳理一下整个过程,帮助理解

首先输入数据,存到paices

定义i从左往右遍历paices,再定义j,从i+1位置开始向后遍历数组,遇到paices[j] <= paices[j-1]就让j结束遍历,遇到paices[j] >paices[j-1]就继续往后遍历。

j遍历结束后,更新结果,并把j的值赋给i

代码实现

cpp 复制代码
#include <iostream>
#include<vector>
using namespace std;

int main() {
    int n;
    cin>>n;
    vector<int> paices(n);
    for(int i=0;i<n;i++)
    {
        cin>>paices[i];
    }
    int ret =0;
    for(int i =0;i<n;)
    {
        int j = i+1;
        while(j<n && paices[j]>paices[j-1])
        {
            j++;
        }
        ret += (paices[j-1] -paices[i]);
        i = j;
    }
    cout<<ret<<endl;
    return 0;
}

三、倒置字符串

题目解析

它们给定我们应该字符串,让我们将其中的单词倒置,但是标点符号不倒置。

例如I like beijing.经过倒置后变成了beijing. like I

算法思路

对于这道题,它只是让我们将其中的单词逆置,如果我们直接去逆置那可以是非常非常难了。

这里来看思路一:

  • 先将整个字符串进行逆置(I like beijing. -> .ginjieb ekil I
  • 然后再遍历字符串,找到每一个单词并进行逆置。(.ginjieb ekil I -> beijing. like I

对于这种思路呢,我们写起来不是很麻烦,但要注意:

我们要使用getline来读取一行。

这里单词直接以隔开,找单词的时候就要以 为找到标准。

这里再来看一种思路:

我们使用cin,它读取到 是读取结束的,那我们使用cin读取一次的结果就是一个单词;这样我们依次读取每一个单词,将它放到数组中,最后逆置一下数组,这样就得到了倒置后单词的一个数组。

这样我们依次输出,并以 隔开即可。

代码实现

这里就只实现第二种思路了,感兴趣可以去实践一下思路一

cpp 复制代码
#include <iostream>
#include <vector>
#include<algorithm>
using namespace std;

int main() {
    string str;
    vector<string> vs;
    while(cin>>str)
    {
        vs.push_back(str);
    }
    reverse(vs.begin(),vs.end());
    for(auto& e:vs)
    {
        cout<<e<<' ';
    }
    cout<<endl;
    return 0;
}

到这里,今日刷题就结束了,感谢各位的支持。
继续加油!!!

相关推荐
勘察加熊人20 分钟前
wpf+c#路径迷宫鼠标绘制
开发语言·c#·wpf
小黄人软件1 小时前
C# ini文件全自动界面配置:打开界面时读ini配置到界面各控件,界面上的控件根据ini文件内容自动生成,点保存时把界面各控件的值写到ini里。
开发语言·c#
二进制人工智能2 小时前
【QT5 网络编程示例】TCP 通信
网络·c++·qt·tcp/ip
Android洋芋4 小时前
C语言深度解析:从零到系统级开发的完整指南
c语言·开发语言·stm32·条件语句·循环语句·结构体与联合体·指针基础
bjxiaxueliang4 小时前
一文详解QT环境搭建:Windows使用CLion配置QT开发环境
开发语言·windows·qt
莫有杯子的龙潭峡谷4 小时前
3.31 代码随想录第三十一天打卡
c++·算法
Run_Teenage5 小时前
C语言 【初始指针】【指针一】
c语言·开发语言
苹果.Python.八宝粥5 小时前
Python第七章02:文件读取的练习
开发语言·python
AaronZZH5 小时前
【进阶】vscode 中使用 cmake 编译调试 C++ 工程
c++·ide·vscode
J不A秃V头A5 小时前
Redis批量操作详解
开发语言·redis