codeforces 1301B Motarack's Birthday 贪心

https://vjudge.net/problem/CodeForces-1301B
在这里插入图片描述题目大意:给一个数组 a a a,如果 a [ i ] = − 1 a[i]=-1 a[i]=1,那么 a [ i ] a[i] a[i]将用 k k k来替代,令 m = M a x ( a b s ( a [ i ] − a [ i − 1 ] ) ) , 2 < = i < = n m=Max(abs(a[i]-a[i-1])),2<=i<=n m=Max(abs(a[i]a[i1])),2<=i<=n。问当 k k k为何值时, m m m是最小的。

思路:首先把不受 k k k影响的部分计算出来,设为 a n s ans ans。然后把受 k k k影响的 a i a_i ai拿出来放到数组 b b b中,设有 l e n len len个元素,那么答案就是: a n s = M a x ( a n s , a b s ( k − b [ i ] ) ) , 1 < = i < = l e n ans=Max(ans,abs(k-b[i])),1<=i<=len ans=Max(ans,abs(kb[i])),1<=i<=len。我们将数组 b b b从大到小排序,不难发现 a b s ( k − b [ i ] ) abs(k-b[i]) abs(kb[i])的最大值要么是 a b s ( k − b [ 1 ] ) abs(k-b[1]) abs(kb[1]),要么是 a b s ( k − b [ l e n ] ) abs(k-b[len]) abs(kb[len]),那么要使这两个值中的最大值最小,自然应该令 k = ( b [ 1 ] + b [ l e n ] ) / 2 k=(b[1]+b[len])/2 k=(b[1]+b[len])/2

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

const int maxn=1e5+5;

int n;
int a[maxn];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        int ans=0,MAX=0,MIN=INF;
        for(int i=2;i<=n;i++)
        {
            if(a[i]==-1&&a[i-1]!=-1)
                MAX=max(MAX,a[i-1]),MIN=min(MIN,a[i-1]);
            else if(a[i]!=-1&&a[i-1]!=-1)
                ans=max(ans,abs(a[i]-a[i-1]));
            else if(a[i]!=-1&&a[i-1]==-1)
                MAX=max(MAX,a[i]),MIN=min(MIN,a[i]);
        }
        if(MIN==INF)
            printf("%d 0\n",ans);
        else
        {
            int mid=MAX+MIN>>1;
            ans=max(ans,max(mid-MIN,MAX-mid));
            printf("%d %d\n",ans,mid);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值