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了

思路是这样的,我们求这些数的和,我们先把这个数sort,然后判断第一个数,如果为非负数的话,也就是这个序列不存在负数,那我们只需要把第一个数减掉就可以了,我们可以不用考虑又多少个加号或者多少个减号,因为我们总是可以找到一组序列满足这个获得最大值的要求,至于其中的加号和减号怎么排列我们不需要考虑了。
如果第一个数为负数,那么我们就需要考虑减号的个数和负数的个数了。我们把是负数的全部都减掉(如果减号够的话)为此我们可以得到最大值。如果负数已经用完但是减号并没有用完,我们也不需要去减掉后面的非负数了,同理我们仍然可以找到满足要求的序列使得式子达到最大。(因为我们减掉非负数的话实际上是把式子的值变小了嘛)
我们也可以用后缀表达式的过程处理,相当于加括号处理,上述过程和后缀表达式差不多其实=-=

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

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

int n, m;
int a[N];
ll sum;

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

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

发布了53 篇原创文章 · 获赞 2 · 访问量 1358

猜你喜欢

转载自blog.csdn.net/qq_44624316/article/details/104545894