题目大意:
给出 n 个史莱姆,每个可以吞噬左边或右边的,然后他的数值变为x- y,询问最终史莱姆的最大值。
解题思路:
如果这些数有正有负,则可以利用负数 - 正数 ,使最后只留下一个正数,再利用正数 - 负数 = 正数 + abs(num),所以有正有负时,输出和的绝对值即可。
如果这些数全正或全负,则最后的值是Σ|a[i]| - min(a[i]) * 2,可以这样想,假设有5个正数 a b c d e 他们的和的绝对值是 sum,我们找出一个最小的数(假设是a)然后吞噬旁边的数,得到非正数(a - b)这样就可以构造有正有负的序列了,所以这个序列的值为 b + c + d + b - a,而总和是sum,则sum - 2min(|a[i]|)就是最后的答案(负数同理,利用a - b 构造非负数即可)。
Code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
const int mod = 1e9 + 7;
const int N = 5e5 + 50;
const int inf = 0x3f3f3f3f;
typedef long long ll;
typedef pair<int, int> pii;
ll a[N];
int main()
{
ll sum = 0, m = 0x7fffffff;
int z = 0, f = 0;
int n;
cin >> n;
for (int i = 1; i <= n; i ++)
{
cin >> a[i];
sum += abs(a[i]);
m = min(m, abs(a[i]));
if (a[i] > 0)
z++;
else if (a[i] < 0)
f++;
}
if (n == 1)
{
cout << a[1] << endl;
return 0;
}
if (z && f)
cout << sum << endl;
else
cout << sum - 2 * m << endl;
return 0;
}