因为 case ‘B’ 后面没有 break,会继续执行 default
因为case‘B’后面没有break,他会继续往下执行
A和C是不可能输出的,写个好理解,A就Breack了,C就进不了循环了,只有B时候赋值给c进入循环进入case "B" 执行输出了c的值B,由于case "B"没有break又进入defaults 执行去了
时间限制: 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 ≤ 10910^9109 。
题解
这题容易被忽视的一点就是转换成中序表达式时候是可以呈现成括号的形式的。
因此这道题应该是分类讨论。
case1:考虑没有负号,则结果为所有数的和。
case2:考虑所有数均为正数且存在负号,则结果为所有数的和减去最小值的2倍。
case3:考虑所有数均为负数且存在负号,则结果为所有数的绝对值之和减去最大值的绝对值的2倍。
case4:考虑所有数存在负数且负数个数大于或等于负号个数,则结果为所有数的绝对值之和。
case5:考虑所有数存在负数且负数个数小于负号个数,则结果为所有数的绝对值之和减去最小自然数的2倍。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 2e5+10;
long long w[maxn];
int main(){
int n, m, f = 0;
long long ans = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n+m+1; i++){
scanf("%lld", &w[i]);
if(w[i] <= 0) f+=1;
}
sort(w+1, w+n+m+2);
if(m == 0){
for(int i = 1; i <= n+m+1; i++){
ans+=w[i];
}
}
else if(f == 0 && f){
for(int i = 2; i <= n+m+1; i++){
ans+=w[i];
}
ans-=w[1];
}
else if(f == n+m+1 && m){
for(int i = 1; i <= n+m; i++){
ans+=w[i];
}
ans = -ans+w[n+m+1];
}
else if(f >= m){
for(int i = 1; i <= n+m+1; i++){
ans+=w[i];
}
ans = -ans;
}
else if(f < m){
bool flag = false;
for(int i = 1; i <= n+m+1; i++){
if(w[i]<0){
ans+=-w[i];
}
else{
if(!flag){
ans-=w[i];
}
else{
ans+=w[i];
flag = true;
}
}
}
}
printf("%lld\n", ans);
return 0;
}