C++实现 蓝桥杯 后缀表达式

题目描述

简单来说给你一串数字,这串数字可以是负数,n个加号和m个减号,问你怎么搭配能得到最大的值

解题思路

前略: 这题在我搞清楚前我觉得有点难的,然后我看了很多题解然后弄明白后发现是真的简单...再说之前我们必须要先明确一件事

后缀表达式是可以带括号的
即一般的后缀表达式23+1-其实是((2+3)-1)


简单来说题目有两种情况

  1. 没有负号的情况
    这个情况最简单,直接全部加起来就行了
  2. 有负号的情况

    这个时候我们需要想想,给你一串数字,怎么减才能得到最大的值呢?很简单,先排完序然后 {大的值} - {小的值} ,这样减出来的值就是最大的。

    但是又因为这串数字可以是负数,我们可以先假设负号数目等于负数数目来思考,那么最大值减去最小值就可以化成 {正数} - {负数和正数} 即是 {正数} + {负数和正数的绝对值}

    但是我们知道负号可以多于负数,我们可以看一串数字{1,2,3,4},负号有2个,正号1个,这时候我们的负号个数就是多于负数的,一般人会认为直接 (((4+3)-2)-1)=4 就行了,但这是错的,正确的是4-(1-(2+3))=8, 注意我的写法,我们可以通过将整数前面添加一个负号,然后把他放到一个带负号的括号里面,这样多余的负号就没有的,原来的正数也因为负负得正没有影响。
    同理多出来的负数也可以把它放在一个带负数的括号里转化为整数
    所以多余的负号可以人为的消去,多余的负数也可以人为转化为正数,那么可以简单认为负号的个数永远等于负数的个数
  3. 由上面的分析可以知道所求最大结果就是 最大值 - 最小值 + 剩余的绝对值 至于为什么要最大值减去最小值,只要假设全部为负号,最多也就是4-(1-2-3)而无法达到4-(-1-2-3)来解决.

分析完毕后,剩下的代码就简单了

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;
typedef long long LL;
const int MAX = 1e5+5;
LL num[2*MAX];

int main() {
	int n,m;
	scanf("%d %d",&n,&m);
	int cnt=n+m+1;
	for(int i=0;i<cnt;i++){
		scanf("%lld",&num[i]);
	}
	LL sum=0;
	if(m==0){//没有负号时
		for(int i=0;i<cnt;i++)sum+=num[i];
		printf("%lld\n",sum);
		return 0;
	}
	//有负号时
	sort(num,num+cnt);
	//最大值减去最小值
	sum+=num[cnt-1];
	sum-=num[0];
	//正数加上绝对值
	for(int i=1;i<cnt-1;i++)sum+=abs(num[i]);
	printf("%lld\n",sum);
	return 0;
}
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值