题目描述
给定 N 个加号、M 个减号以及 N+M+1 个整数 A1,A2,⋅⋅⋅,AN+M+1,小明想知道在所有由这N 个加号、M 个减号以及 N+M+1 个整数凑出的合法的 后缀表达式中,结果最大的是哪一个?
请你输出这个最大的结果。
例如使用 1 2 3 + -,则 "2 3 + 1 -" 这个后缀表达式结果是 4,是最大的。
输入描述
第一行包含两个整数 N,M。
第二行包含 N+M+1 个整数 A1,A2,⋅⋅⋅,AN+M+1。
其中,0≤N,M≤105,−≤Ai≤
。
输出描述
输出一个整,代表答案。
输入输出样例
示例
输入
1 1
1 2 3
输出
4
中缀转后缀的顺序是固定的:
转换算法遵循明确的规则(如运算符优先级和结合性)
使用栈结构保证了确定的处理顺序
结果后缀表达式能唯一反映原中缀表达式的运算顺序
例如:
(3 + 4) × 5 - 6
只能转换为3 4 + 5 × 6 -
后缀转中缀的顺序不固定:
运算符优先级的影响:相同的后缀表达式可能对应不同括号位置的中缀表达式
例如:
3 4 + 5 ×
可转为(3 + 4) × 5
或3 + 4 × 5
(后者数学等价但括号位置不同)结合性的影响:相同优先级的运算符可能有不同分组方式
例如:
3 4 5 + +
可转为3 + (4 + 5)
或(3 + 4) + 5
交换律的影响:可交换运算符(如+、×)的操作数顺序可以交换
例如:
2 3 ×
可转为2 × 3
或3 × 2
后缀转中缀中可以随意加括号、交换运算符的顺序
思路:
1.如果没有减号,最大的结果就是n+m+1个数的和
2. 如果有减号:最终只有1个减号起作用,其他减号可以抵消
与负数匹配的减号——负负得正,相消
与负数匹配的加号——放到第一个减号里
eg: -5, -3, 1, 2, +, -, - 2 - ((-5)+(-3)) +1
与正数匹配的减号——放到第一个减号里
eg: 1, 2, 3, 5, -, -, - 5 - (1-2-3)
与正数匹配的加号——正好
所以,最后的结果就是最大数-最小数+其他数的绝对值
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;int a[200010];
long long ans; //必须开long long int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int n, m; //加号、减号的个数 cin>>n>>m;int cnt=n+m+1;for(int i=1; i<=cnt; ++i) cin>>a[i];sort(a+1, a+cnt+1);//如果没有减号 if(m==0){ for(int i=1; i<=cnt; ++i) ans += a[i];cout<<ans;return 0; }ans = a[cnt]-a[1];for(int i=2; i<=cnt-1; ++i){ans += abs(a[i]); }cout<<ans;return 0;
}