试题 I:后缀表达式
如题~
【问题描述】
给定 N个加号、M个减号以及 N+M+1个整数 A1,A2,···,AN+M+1,小
明想知道在所有由这N个加号、M个减号以及N+M+1个整数凑出的合法的
后缀表达式中,结果最大的是哪一个?
请你输出这个最大的结果。
例如使用123±,则“23+1-”这个后缀表达式结果是4,是最大的。
【输入格式】
第一行包含两个整数N和 M。
第二行包含N+M+1个整数A1,A2,···,AN+M+1。
【输出格式】
输出一个整数,代表答案。
【样例输入】
11
123
【样例输出】
4
【评测用例规模与约定】
对于所有评测用例,0≤N,M≤100000,−10e9 ≤Ai≤10e9。
首先这个题你需要知道后缀表达式是什么。
。开始我不知道,磨了好久,看的别家大佬的,百度的,我才懂。
下面讲解开始:
后缀表达式不再引用括号,也就是说,你想在哪里用括号就在哪里用括号就行。
比如给你5个数,一个 + 和三个 - 号。
如果,五个数 1 2 3 4 5 全是正数的话。答案自然就是 5 + 4 - 3 - 2 - 1
但是如果五个数是 1 -2 -3 -4 -5,这又怎么算呢。可以这样算
1-(-5)-(-4)-(-3)+(-2)这是正常思路。
但也可以这样做,在后缀表达式中。
1-(-5)-((-4)+(-3))-(-2),这个答案比上面那个数还要大
多找一些数字,可以总结规律
如果全是加号,答案就是所有数字直接相加。
如果存在减号:
如果全是正数,那么至少有一个被减去,所以把最小的那个减去即可。
如果有正有负,可以利用上面的例子,总是可以把所有数的绝对值加起来。
如果全是负数,除了绝对值最小的负数,给他留着。其他的全部可以变为正数。
代码如下:
#include<bits/stdc++.h>
using namespace std;
long long int a[200005], sum = 0, minx = 1000000001;
int n, m, fsign = 0;
int main()
{
scanf("%d%d", &n, &m);//n m 的值
for (int i = 0; i < n + m + 1; i++)
{
scanf("%lld", &a[i]);
if (a[i] < 0) fsign++;
sum += a[i];
minx = min(minx, a[i]);
}
if (m == 0) printf("%lld\n", sum);//没有负号存在时,sum就是所有数的和
else//负号存在
{
if(fsign == 0)//负数为零情况下,就是所有数之和,再-最小值两遍就行。(详见开头讲解)
{
printf("%lld\n", sum - minx - minx);
}
else
{
if (fsign == n + m + 1) //全是负数的情况,自然有办法给他弄成整数
{
sum = 0; minx = 1000000001;
for (int i = 0; i < n + m + 1; ++i)
{
sum += abs(a[i]);//都是绝对值之和
minx = min(minx, abs(a[i]));//把绝对值最小挑出来减去
}
printf("%lld\n", sum - minx - minx);
}
else
{
sum = 0;
for (int i = 0; i < n + m + 1; ++i)
{
sum += abs(a[i]);
}
printf("%lld\n", sum);
}
}
}
return 0;
}
应该是对的。。
该博客介绍了如何解决后缀表达式的问题,当给定一定数量的加号、减号和整数时,如何找到能得出最大结果的合法表达式。博主首先解释了后缀表达式的概念,并给出了不同情况下的计算策略:没有减号时直接相加,有减号时根据正负数情况调整。然后提供了一个C++代码示例来计算最大结果,考虑了全正数、全负数和混合正负数的情况。
248

被折叠的 条评论
为什么被折叠?



