B. Equalize Prices

B. Equalize Prices

在这里插入图片描述

Example

input

4
5 1
1 1 2 3 1
4 2
6 4 8 5
2 2
1 6
3 5
5 2 5

output

2
6
-1
7

在这里插入图片描述

题目大意:

给一个数组,可以把每个元素的值改成[a-k,a+k]以内,使得每个元素相等,求最大值。

思路:

这题虽然只有900的难度,但很有意思,它可以用不止一种方法做(感觉cf上的题大多都有这种特性)。

我首先想到的是二分…

第二种是思维+数学,因为要让所有数最后都变成一样,所以只需要考虑最大和最小的值之差,是否超过2 * k,因为如果不超过,可以让最小值+k,最大值-k,最后肯定可以相等,此时答案就是最小值+k。如果超过了2 * k,就不可能有答案,所以输出-1.

代码:

二分版本

#include<algorithm>
#include<iostream>
#include<cmath>
#define int long long
using namespace std;
const int N=5050;
const int INF=0x3f3f3f3f;

int a[N];
int n,k;

bool check(int mid)
{
    
    
    for(int i=0;i<n;++i)
    {
    
    
        if(abs(a[i]-mid)>k)return 0;
    }
    return 1;
}

signed main()
{
    
    
    int t;
    cin>>t;
    while(t--)
    {
    
    
        cin>>n>>k;
        int Min=INF;
        int Max=-1;
        for(int i=0;i<n;++i)
        {
    
    
            cin>>a[i];
            Max=max(Max,a[i]);
            Min=min(Min,a[i]);
        }
        int l=Min-k;
        int r=Max+k;
        int ans=-1;
        while(l<r)
        {
    
    
            int mid=l+r+1>>1;
            if(check(mid))//小了,但是符合答案
            {
    
    
                ans=mid;
                l=mid;
            }
            else
            {
    
    
                r=mid-1;
            }
        }
        cout<<ans<<endl;
    }
	return 0;
}

思维+数学 版本:

#include<algorithm>
#include<iostream>
#include<cmath>
#define int long long
using namespace std;
const int N=5050;
const int INF=0x3f3f3f3f;

signed main()
{
    
    
    int t;
    cin>>t;
    while(t--)
    {
    
    
        int n,k;
        cin>>n>>k;
        int Min=INF;
        int Max=-1;
        for(int i=0;i<n;++i)
        {
    
    
            int a;
            cin>>a;
            Max=max(Max,a);
            Min=min(Min,a);
        }
        int ans=Max-Min;
        if(ans>2*k)cout<<-1<<endl;
        else cout<<Min+k<<endl;
    }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Story_1419/article/details/117356532