2019年第十届蓝桥杯B组省赛(C++)I题

2019年第十届蓝桥杯B组省赛(C++)I题

后缀表达式

传送门
1
最近做一点蓝桥的题目,我很慌(真),慌的一批。训练一下大脑吧,毕竟最近网课太多加上搞网站,就没怎么敲代码,啊啊啊啊。纠结超慌,不得不写点题目。先开始打算题解直接在网站上面写的,github只给了500M的内存,不忍心,题解还是在CSDN上面写吧。。github写Unity3d等的一些开发内容,打算认真搞AI后经验会在上面写。

有点坑坑,我先开始做的时候用贪心处理的,结果找出一组反例,我内心??what,比如四个减号,一个加号,数据是-1,-2,-3,1,2,3
用贪心处理的话是10,但是答案是12!!我左算右算才得到12的。。脑子转不过来。用后缀表达式处理康康,也叫做逆波兰式,我们可以用如下式子得到最大值:
3 + 2 - (-1 - 1)-(-2)-(-3)
这样算出来的答案就是12了

思路是这样的:
如果没有减号,那我们只能把所有得数字都给加起来输出就行。
如果有减号,我们首先把这个数组先排序,我所得到得最大值其实就是加上一个最大值,减去一个最小值,其余的加绝对值,这是为什么呢?
我们最好的策略就是减去负数,加上正数:
如果只有一个减号,那我们只需要减去最小的数;
如果只有一个加号,那我们得加上那个最大的数;
那么中间的情况我们可以通过添加括号全部实现加上正数的情况;
比如1 2 3 4 5
两个加号,两个减号
那么可以写成5 + 4 + 3 - (1 - 2)
把括号一拆开就是 5 + 4 + 3 - 1 + 2;符合上面的描述
比如-1, -2, 3, 4, 5
三个加号,一个减号
可以写成 5 + 4 + 3 - (-1 - 2);符合上面描述

我们也可以用后缀表达式的过程处理,相当于加括号处理,上述过程和后缀表达式差不多其实=-=

好啦上代码啦,由于没有题目链接,我就直接截图啦~

#include <bits/stdc++.h>
using namespace std;
const int N = 2 * 1e5 + 10;
typedef long long ll;

int a[N];

int main()
{
	ll ans = 0;
	int n, m;
	scanf ("%d%d", &n, &m);
	int k = n + m + 1;
	for (int i = 0; i < k; i++)
	{
		scanf ("%d", &a[i]);
	}
	if (!m)
	{
		for (int i = 0; i < k; i++)
		{
			ans += 1ll * a[i];
		}
		cout << ans << endl;
	}
	else
	{
		sort(a, a + k);
		ans += a[k - 1];
		ans -= a[0];
		for (int i = 1; i < k - 1; i++)
		{
			ans += abs(a[i]);
		}
		cout << ans << endl;
	}
	return 0;
} 

大家可以自行验证一下~有错误欢迎指正哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

娃娃酱斯密酱

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值