codeforces 1038 D. Slime 思维, 数字合并最大值

题目链接: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;
}

发布了374 篇原创文章 · 获赞 22 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_21433411/article/details/103192680