第十届 蓝桥杯 C、C++程序设计 本科B组 第9题 后缀表达式(带注释)

博客介绍了如何解决蓝桥杯比赛中关于后缀表达式的问题,通过分析输入数据的四种情况,找到计算最大结果的方法。文章提供了详细解题思路和示例,包括只有加号、只有负数、有加减号但无负数以及有加减号和负数的情况,并给出相应计算示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

试题 I: 后缀表达式

时间限制: 1.0s 内存限制: 256.0MB 本题总分:25 分

【问题描述】

给定 N 个加号、M 个减号以及 N + M + 1 个整数 A 1 ,A 2 ,··· ,A N+M+1 ,小明想知道在所有由这 N 个加号、M 个减号以及 N + M +1 个整数凑出的合法的后缀表达式中,结果最大的是哪一个?
请你输出这个最大的结果。
例如使用1 2 3 + -,则 “2 3 + 1 -” 这个后缀表达式结果是 4,是最大的。
【输入格式】
第一行包含两个整数 N 和 M。
第二行包含 N + M + 1 个整数 A 1 ,A 2 ,··· ,A N+M+1 。
【输出格式】
输出一个整数,代表答案。
【样例输入】
1 1
1 2 3
【样例输出】
4

【评测用例规模与约定】
对于所有评测用例,0 ≤ N, M ≤ 100000,−10^9 ≤ A i ≤ 10^9 。

解题思路:

前言(废话):首先,题目说是后缀表达式,我第一个想到的是用数据结构里栈里的那种后缀表达式的规则去计算,但是题目又说 “求所有由这 N 个加号、M 个减号以及 N + M +1 个整数凑出的合法的后缀表达式中,结果最大的是哪一个”,那这样的话 结果和后缀表达式好像没有什么关系啊??。。额…如果只是求它们的最大结果,请看下文:

对于输入的数据,可以分为四种情况:

  1. 只有“+”号:
    此时不论输入的数据是否有负数,只需将所有的输入加起来即可;
    例:

input:
0 2
1 2 3
output:
6
说明:1+2+3=6

  1. 只有负数
    此时需要牺牲掉最大负数(即绝对值最小的负数),我也是将所有的数先相加,因为有负数 所以采用绝对值的方式相加。最后结果-最大负数的绝对值*2
    例:

input:
1 2
-1 -2 -3 -4
output:
8
说明:
-1-[(-4)+(-3)]-(-2)=-1+4+3+2=8

  1. 情况3:有"+","-",无负数
    此时需要牺牲最小正数,将所有数相加,最后结果-最小正数*2

input:
1 1
1 2 3
output:
4
说明:
3+2-1=4

  1. 有"+","-",负数
    此时,将所有正数和+所有负数绝对值的和即可。

input:
1 2
1 2 3 -4
output:
10
说明:
1-(-4-2)+3=1+4+2+3=10

测试了一些数据,目前还没发现不对的。
代码如下:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {
	int n,m,i; 
	int neg=0,pos=0;   //负数和正数的个数 
	int a[200005]={0};
	cin>>n>>m;
	int len=m+n+1;
	for(i=0;i<len;i++){
		cin>>a[i];
		if(a[i]<0){
			neg++;  //负数个数 
		}
		else
			pos++;	//正数个数	 
	}
	sort(a,a+len);
	//n为"+",m为"-"
	long long ans=0;
	//情况1:只有 "+"号 
	if(m==0){
		for(i=0;i<len;i++)
			ans+=a[i];
	} 
	
	else{
		//情况2:只有负数,pos=0,最后结果-最大负数*2 (牺牲最大负数)
		if(pos==0){
			for(i=0;i<neg;i++){
				ans+=abs(a[i]);
			}
			ans=ans-abs(a[neg-1])-abs(a[neg-1]);
		}
		//情况3:有"+","-",无负数,neg=0   (牺牲最小正数)
		else if(neg==0){
			for(i=0;i<len;i++){
				ans+=a[i];
			}
			ans=ans-a[neg]*2;
		} 
		//情况4:有"+","-",负数  (所有正数和+所有负数绝对值的和)
		else{
			for(i=0;i<len;i++)
			ans+=abs(a[i]);
		}
	}
	
	cout<<ans<<endl;
	 
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值