题目描述
解法:二分(C++)
我们先说明二分是可以的:
这道题呢,就相当于,对于每一个状态下的数组,我们需要找到某一点到其他所有点的距离最小。易知的是,这个点就是中位数点。
我们设第 x x x 天刚好满足条件,那么从第 x − 1 x-1 x−1 天往后,总是可以通过魔法来使高度一致。
于是,我们就得知,存在这样一个恰好满足条件的天数,在这之前无法保证高度一致,在这之后所有的时间高度都保证一致,二分法得证。
最后剩下的问题就是,每天都有高度在变化,在 h e l p e r ( ) helper() helper() 中,我们借助了 b [ . . . ] b[...] b[...] 数组来记录每天的高度,然后计算出偏差和,判断其是否小于当前的天数,如果小于,那么就说明是可以通过魔法消除高度差,这样,当前的天数是能满足条件的。于是,继续下一步搜索,找到刚好满足条件的天数。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
long long a[N], b[N];
int n;
bool helper(long long x){
for(int i=1;i<=n;i++)
b[i] = a[i]+x/n+(x%n>=i);
sort(b+1, b+1+n);
long long res = 0;
for(int i=1;i<=n;i++)
res += abs(b[i]-b[(n+1)/2]);
return res<=x;
}
int main()
{
cin >> n;
for(int i=1;i<=n;i++)
cin >> a[i];
long long left = 1, right = 1e14, mid;
while(left<=right)
{
mid = left+(right-left)/2;
if(helper(mid)) right = mid-1;
else left = mid+1;
}
cout << left << endl;
return 0;
}