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;
}