后缀表达式 | 第十届蓝桥杯省赛C++B组
给定 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。
输出格式
输出一个整数,代表答案。
数据范围
0≤N,M≤105,
−109≤Ai≤109
输入样例:
1 1
1 2 3
输出样例:
4
题解:
提前看了tag,知道了用贪心解。
分析题目,发现每个数都要匹配一个符号,除了第一个数必定为正。
降序排序数列,得到最大值和最小值,将最大值放第一个,最小值放第二个并加一个括号:
这个时候,当你有个正数时,你有个加号就放前面加,你有个减号时就放后面括号里也是加。
当你有个负数,你有加号就放后面括号里,你有减号就直接减放前面。
则你除了最大和最小数都可以实现加,也就是绝对值的和。
注意:1.在求和后要重新处理最大值和最小值,不能直接加。
2.当m=0时是求所有数的和,是特殊情况。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
#include<vector>
#include<unordered_set>
#include<unordered_map>
#include<map>
#include<set>
using namespace std;
typedef long long int ll;
int N=0,M=0;
vector<int> vt;
long long int sum=0;
long long int sp_sum=0;
int cmp(int a,int b){
return a>b;
}
int main(){
cin >> N >> M;
for(int i=0;i<N+M+1;i++){
int t;
cin >> t;
vt.push_back(t);
sum+=abs(t);
sp_sum+=t;
}
//cout << sum << "\n";
sort(vt.begin(),vt.end(),cmp);
sum-=abs(vt[0]);
sum+=vt[0];
sum-=abs(vt[vt.size()-1]);
sum-=vt[vt.size()-1];
if(M==0){
cout << sp_sum;
}
else{
cout << sum << "\n";
}
/*
for(int i=0;i<vt.size();i++){
cout << vt[i] << " ";
}
cout << "\n";
*/
}