输入样例:
1 1
1 2 3
输出样例:
4
解题思路:
看完这道题的第一感觉就是排序后,将较大值都相加,将较小值都相减,但这种做法是错误的。
后缀表达式,又叫逆波兰式,对应于树的后序遍历。例如 12-,对应与:1-2;又如:123--,对应于:1-(2-3)。可以看出3-2-1并不是最大值;还可以看出:后缀表达式转中缀表达式时可以加括号,而加括号后括号内的负号与括号外的符号就变成了正号!
那么负号的个数有没有范围?事实上,当m(表示负号的个数)==0时,最大值就是所有的数相加;当 m = N > 0 时,除了括号内的第一个数不能变为正数外,括号内的其它数都可以为正数,所以负号的个数范围为 [ 1, N ] 。相当于在一些负号里,只有一个数真正的是负数,其他数都可以变为正数。当还有 n个正号时,因为通过将正号放到括号内或外再次变为负号,所以负号的范围就成了:[ 1, N + n ]。
意味着只要给定大于0个负号,就可以将所有的数都变为正数,除了表达式的第一个数a需要保留,还有括号内的第一个数b需要变相反号;所以将序列中的最大值赋给a,最小值付给b,其余值均变为正值,算出的就是最大值。
后缀表达式:123-- 转为中缀表达式:1-(2-3) 可以通过栈实现。操作步骤为:
- 依次遍历后缀表达式,当遍历到数字时,将数字压栈。
- 当遍历到符号时f,从栈中依次弹出栈顶元素x,次栈顶元素y,将 y f x 的值继续压入栈。直到遍历结束。
例如:123-- :将1,2,3 依次压入栈,当遍历到 - 时,将x = 3,y = 2,2 - 3 = -1, 将 -1 压栈,遍历到最后一个 - 时,弹出元素 x = -1,y = 1,y - x = 1 - (-1) = 2,遍历结束,结果为2.
Java代码:
import java.io.*;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] split = br.readLine().split(" ");
int n = Integer.parseInt(split[0]);
int m = Integer.parseInt(split[1]);
int l = n + m + 1;
int []arr = new int [l];
split = br.readLine().split(" ");
for(int i = 0; i < l; i++)
arr[i] = Integer.parseInt(split[i]);
Arrays.sort(arr);
long ans = 0;
if(m == 0) {
for(int i = 0; i < l; i++)
ans += arr[i];
}else {
ans = arr[l - 1] - arr[0];
for(int i = 1; i < l - 1; i++)
ans += Math.abs(arr[i]);
}
System.out.println(ans);
}
}