题目链接:https://codeforces.com/contest/1038/problem/D
题目大意:题意是有n个史莱姆,每一个史莱姆都可以吃掉相邻的史莱姆,使得自己的值改变,当x吃掉y的时候,x的值变为x-y,问最后所剩下的史莱姆最大是多少。
三种情况,第一种是所有数都是正数,对于这种情况我们要找一个最小值去减去一个数来获得一个负数,然后用这个负数去减别的正数从而获得更小的负数,最后再用一个正数来减去这个负数从而获得最大值,在这个过程中我们可以发现所有值最终都是被加上的,除了最小值第一次减的时候没有加上以外还少算了一次最小值,所以最终ans就是所有数的和减去2Min,解释的不太好理解,可以写一下这个过程想想,同理当所有数都是负数的时候就是所有数的绝对值的和减去2Max,
当既有正数又有负数的时候就是输出所有元素的绝对值的和。
这里可以怎么一下:如果a, b相邻,并且a,b异号,那么用负-正,得到
负。最后的状态就是一正一负。然后正-负。
然后就是对于n等于1和2的情况特判一下就好了。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
LL a[500005], z=0, f=0;
int main()
{
int n;
scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%lld", &a[i]);
if(a[i]>0){
z++;
}
else if(a[i]<0){
f++;
}
}
if(n==1){
printf("%lld\n", a[1]);
return 0;
}
else if(n==2){
printf("%lld\n", abs(a[1]-a[2]));
return 0;
}
LL ans=0, mi=1ll<<50, mx=-1ll<<50;
if(z&&!f){//全部正数
for(int i=1; i<=n; i++){
mi=min(1ll*a[i], mi);
ans+=a[i];
}
printf("%lld\n", ans-2*mi);
return 0;
}
if(!z&&f){//全部负数
for(int i=1; i<=n; i++){
mx=max(1ll*a[i], mx);
ans+=abs(a[i]);
}
printf("%lld\n", ans-2*abs(mx));
return 0;
}
for(int i=1; i<=n; i++){
ans+=abs(a[i]);
}
printf("%lld\n", ans);
return 0;
}