【刷题汇总 --游游的水果大礼包、买卖股票的最好时机(二)、倒置字符串】

今日刷题汇总 - day011

1、游游的水果大礼包

1.1、题目

在这里插入图片描述

1.2、思路

读完题知道,将n个苹果和m个桃子,按照一定比例组成不同价值的一号或二号礼包,求最多组成礼包的总价值。那么,通常类似的题都使用贪心法,尽可能让价值高的礼包,尽可能地多选,然后这道题不适用,很容易举反例。那么,就只好使用枚举了,也就是蛮力法,让一号礼包组成0个,二号礼包全选,接一号礼包选1个,而二号礼包选全选-1个,接着2个一号,n-2个二号礼包…直到1号全选,二号不选即可。期间不断更新最大价值,最后返回得到地最大价值即可。接下来,就是程序实现。

1.3、程序实现

首先,按照题目要求输入数据,注意数据范围超出这里使用long long,然后,根据1号礼包的苹果和桃子的比例,以及二号礼包的比例,推导边界控制,为了直观的理解,画个图:
在这里插入图片描述
所以推导1号礼包最多情况是由苹果决定的,而影响苹果使用个数的由n/2和m决定,所以取最小值得到1号礼包的最多能组成的数目,即边界控制:[0,min(n/2,m)]; 同理,二号礼包边界控制推导就是再减去一号礼包已使用个数之后得到:[n-i*2,(m-i)/2];最后由变量ret得到每次枚举的最大价值输出即可。总结这道题就是要分析处理好组装的比例关系,由关系推导价值求解即可。

#include <iostream>
using namespace std;
long long n, m, a, b;
int main()
{ 
    cin >> n >> m >> a >> b;
    long long ret = 0;
    for(long long x = 0;x <= min(n/2,m);x++)
    {
        long long y = min(n-x*2,(m-x)/2);
        ret = max(ret,a*x+b*y);
    }
    cout << ret << endl;
     return 0;
}

在这里插入图片描述
在这里插入图片描述

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

2.1、题目

在这里插入图片描述

2.2、思路

读完题,知道与上篇的买卖股票的最好时机(一)的区别在于,可以反复买卖股票,让其获得最大收益即可。上道题利用的逆向思维,从卖点入手,遍历卖点之前的价值,得到最小值从而求差值得到最大利润。那么这道题,由于可以反复够吗,那么从给的示例的上帝视角分析,发现只要买入的后面在涨就买,在跌点的前一个点就卖,反复如此,利润绝对就是最大值。为了方便理解,画个图:
在这里插入图片描述
那么接下来,就是程序实现。

2.3、程序实现

首先,按照题目要求完成输入,然后定义一个变量retsum表示最后的最大利润,接着直接遍历,只要第二天大于第一天就买入再卖出,求得每一段的利润累计到retsumu最后输出即可。

#include <iostream>
using namespace std;

const int N = 1e5 + 10;

int prices[N];

int main()
{
    int n;
    cin >> n;
    for(int i = 0;i < n; i++)
        cin >> prices[i];
    
    int retsum = 0;
    for(int i = 1;i < n; i++)
    {
        if(prices[i] - prices[i-1] > 0)
            retsum += (prices[i] - prices[i-1]);
    }
    cout << retsum << endl;
    return 0;
}

在这里插入图片描述
在这里插入图片描述

3、倒置字符串

3.1、题目

在这里插入图片描述

3.2、思路

读完题,知道,让我们逆置单词字符串,意味着逆置单词的位置,而不逆置字母顺序。这道题,跟很久以前C语言写过的单纯的逆置字符串题类似,那么根据示例分析,只需要交换单词的位置,再将每个单词单独逆置即可,其中注意标点符号和空格的处理即可。那么,这里涉及到逆置,先用C语言写,再用C++写,因为C++直接可以调用alogrithm算法库的reverse逆置比较方便。为了搞清楚思维过程,所以先用C语言实现。那么接下来,就是程序实现。

3.3、程序实现 – c语言

根据思路的分析,可以分为以下几个步骤:
(1)、逆置整个字符串,目的是实现单词的位置正确;
(2)、再根据空格与指针划分,每个单词;
(3)、逆置单独的每个单词,最后输出即可;
为了方便理解,画个图:
在这里插入图片描述
思路清晰后,完成C程序,首先定义满足数据范围的字符数组str,用gets完成带空格的字符串输入,因为scanf是以空格或回车等这类不显示字符作为判定输入结束的,所以用gets即可,接着封装一个reverse函数,传入指针交换两侧向中间走,完成字符串逆置,然后,利用工作指针start和end分别标记单词的开头和结尾,然后再逐步逆置单词,只要注意控制好end与空格的处理即可,最后数据str即可。

#include <stdio.h>
#include <string.h>

void reverse(char* left, char* right )
{
	while (left < right) {
		char tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
}

int main()
{	
	char str[101] = { 0 };
	gets(str);
	int len = strlen(str) - 1;
	reverse(str, str+len);
	char* start = str;
	while (*start)
	{
		char* end = start;
		while (*end != ' ' && *end != '\0')
		{
			end++;
		}
		reverse(start, end - 1);
		if (*end == ' ')
		{
			start = end+1;
		}
		else
		{
			start = end;
		}
	}
	printf("%s\n", str);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

3.4、程序实现 – c++

首先,还是按照思路分析,完成C++代码即可。注意其中输入用getline输入一行,调用algorithm算法库的reverse逆置,以及空格处理即可。

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    string str;
    getline(cin , str);
    reverse(str.begin(),str.end());

    int start = 0;
    int end = 0;
    size_t len = str.size();
    while(start < len)
    {
        end = start;
        while(end < len && str[end] != ' ') 
        {
            end++;
        }
        reverse(str.begin() + start, str.begin() + end);
        while(end < len && str[end] == ' ') 
            end++;
        start = end;
    }
    cout << str <<endl;
    return 0;
}

在这里插入图片描述
在这里插入图片描述

4、题目链接

游游的水果大礼包
买卖股票的最好时机(二)
倒置字符串

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据题目描述,游游有n个苹果和m个桃子,可以组成两种不同价值的大礼包。一种是价值a元的一号水果大礼包,由2个苹果和1个桃子组成;另一种是价值b元的水果大礼包,由1个苹果和2个桃子组成。现在游游想知道,她最多能组成多少价值总和的大礼包。 我们可以通过贪心算法来解决这个问题。贪心算法的思路是每次选择能得到最大价值的大礼包组合,直到无再选择。 首先,我们可以先尽可能多地选择一号水果大礼包。每次选择一号水果大礼包时,我们可以消耗掉2个苹果和1个桃子,并获得价值a元。如果剩余的苹果数量小于2或者剩余的桃子数量小于1,就无再选择一号水果大礼包了。 接下来,如果还有剩余的苹果或者桃子,我们可以选择水果大礼包。每次选择水果大礼包时,我们可以消耗掉1个苹果和2个桃子,并获得价值b元。如果剩余的苹果数量小于1或者剩余的桃子数量小于2,就无再选择水果大礼包了。 最后,游游能够得到的最大价值总和的大礼包就是选择一号水果大礼包的次数乘以a,再加上选择水果大礼包的次数乘以b。 具体的实现可以参考下面的代码: ```cpp #include <iostream> using namespace std; int main() { int n, m, a, b; cin >> n >> m >> a >> b; int maxPackage = 0; // 尽可能多地选择一号水果大礼包 while (n >= 2 && m >= 1) { maxPackage++; n -= 2; m -= 1; } // 尽可能多地选择水果大礼包 while (n >= 1 && m >= 2) { maxPackage++; n -= 1; m -= 2; } int maxTotalValue = maxPackage * max(a, b); cout << maxTotalValue << endl; return 0; } ``` 希望能帮到你!如果还有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值