试题 I:后缀表达式(套题)

该博客介绍了如何解决后缀表达式的问题,当给定一定数量的加号、减号和整数时,如何找到能得出最大结果的合法表达式。博主首先解释了后缀表达式的概念,并给出了不同情况下的计算策略:没有减号时直接相加,有减号时根据正负数情况调整。然后提供了一个C++代码示例来计算最大结果,考虑了全正数、全负数和混合正负数的情况。

试题 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;
}

应该是对的。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值